Suppose I create a class with some methods: py> class C: ... def spam(self, x): ... print "spam " * x ... def ham(self, x): ... print "ham * %s" % x ... py> C().spam(3) spam spam spam >>> C().ham(3) ham * 3
To dynamically remove the methods, delete them from the class like you would any other attribute: py> del C.ham py> C().ham(3) Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: C instance has no attribute 'ham' That's fairly straight forward -- no major surprises there. How does one dynamically add methods to an instance or class? You might think you can do this: py> def eggs(self, x): ... print "eggs * %s" % x ... py> inst = C() py> inst.eggs = eggs py> inst.eggs(3) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: eggs() takes exactly 2 arguments (1 given) Even though we've added a function to the instance, it hasn't got all the machinery to work as a proper method. A work-around is to explicitly pass an instance: py> inst.eggs(inst, 3) eggs * 3 To create a proper method, we do this: py> import new py> inst.eggs = new.instancemethod(eggs, None, C) py> inst.eggs(3) eggs * 3 You can now delete the top-level function eggs, and the method bound to inst will not be affected. Because eggs is bound to the instance, new instances will not understand it: py> C().eggs(3) Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: C instance has no attribute 'eggs' Or you could put the method in the class and have all instances recognise it: py> C.eggs = new.instancemethod(eggs, None, C) py> C().eggs(3) eggs * 3 Instead of passing None as the second argument to instancemethod, you can pass an instance. If you do that, self will automatically be set to that instance instead of the one doing the calling: py> def truffles(self, x): ... print self, x ... py> C.truffles = new.instancemethod(truffles, inst, C) py> inst <__main__.C instance at 0xf6d2d6cc> py> inst.truffles(3) <__main__.C instance at 0xf6d2d6cc> 3 No surprises there. But look what happens when we use a new instance: py> x = C() py> x <__main__.C instance at 0xf6d2ca6c> >>> x.truffles(3) <__main__.C instance at 0xf6d2d6cc> 3 Hope this is useful to some folks. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list