Python: changing methods and attributes at runtime Python: changing methods and attributes at runtime python python

Python: changing methods and attributes at runtime


This example shows the differences between adding a method to a class and to an instance.

>>> class Dog():...     def __init__(self, name):...             self.name = name...>>> skip = Dog('Skip')>>> spot = Dog('Spot')>>> def talk(self):...     print 'Hi, my name is ' + self.name...>>> Dog.talk = talk # add method to class>>> skip.talk()Hi, my name is Skip>>> spot.talk()Hi, my name is Spot>>> del Dog.talk # remove method from class>>> skip.talk() # won't work anymoreTraceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: Dog instance has no attribute 'talk'>>> import types>>> f = types.MethodType(talk, skip, Dog)>>> skip.talk = f # add method to specific instance>>> skip.talk()Hi, my name is Skip>>> spot.talk() # won't work, since we only modified skipTraceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: Dog instance has no attribute 'talk'


I wish to create a class in Python that I can add and remove attributes and methods.

import typesclass SpecialClass(object):    @classmethod    def removeVariable(cls, name):        return delattr(cls, name)    @classmethod    def addMethod(cls, func):        return setattr(cls, func.__name__, types.MethodType(func, cls))def hello(self, n):    print ninstance = SpecialClass()SpecialClass.addMethod(hello)>>> SpecialClass.hello(5)5>>> instance.hello(6)6>>> SpecialClass.removeVariable("hello")>>> instance.hello(7)Traceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: 'SpecialClass' object has no attribute 'hello'>>> SpecialClass.hello(8)Traceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: type object 'SpecialClass' has no attribute 'hello'


A possibly interesting alternative to using types.MethodType in:

>>> f = types.MethodType(talk, puppy, Dog)>>> puppy.talk = f # add method to specific instance

would be to exploit the fact that functions are descriptors:

>>> puppy.talk = talk.__get__(puppy, Dog)