Is it possible to change an instance's method implementation without changing all other instances of the same class?

Since Python 2.6, you should use the types module's MethodType class:

from types import MethodType

class A(object):
    def m(self):
        print 'aaa'

a = A()

def new_m(self):
    print 'bbb'

a.m = MethodType(new_m, a)

As another answer pointed out, however, this will not work for 'magic' methods of new-style classes, such as __str__().


This answer is outdated; the answer below works with modern Python

Everything you wanted to know about Python Attributes and Methods.

Yes, this is an indirect answer, but it demonstrates a number of techniques and explains some of the more intricate details and "magic".

For a "more direct" answer, consider python's new module. In particular, look at the instancemethod function which allows "binding" a method to an instance -- in this case, that would allow you to use "self" in the method.

import new
class Z(object):
  pass
z = Z() 
def method(self):
  return self
z.q = new.instancemethod(method, z, None)
z is z.q()  # true

If you ever need to do it for a special method (which, for a new-style class -- which is what you should always be using and the only kind in Python 3 -- is looked up on the class, not the instance), you can just make a per-instance class, e.g....:

self.foo = Foo()
meths = {'__str__': lambda self: 'peekaboo!'}
self.foo.__class__ = type('yFoo', (Foo,), meths)

Edit: I've been asked to clarify the advantages of this approach wrt new.instancemethod...:

>>> class X(object): 
...   def __str__(self): return 'baah'
... 
>>> x=X()
>>> y=X()
>>> print x, y
baah baah
>>> x.__str__ = new.instancemethod(lambda self: 'boo!', x)
>>> print x, y
baah baah

As you can see, the new.instancemethod is totally useless in this case. OTOH...:

>>> x.__class__=type('X',(X,),{'__str__':lambda self:'boo!'})
>>> print x, y
boo! baah

...assigning a new class works great for this case and every other. BTW, as I hope is clear, once you've done this to a given instance you can then later add more method and other class attributes to its x.__class__ and intrinsically affect only that one instance!

Tags:

Python