hofer a écrit :
Hi,
I have multiple objects all belonging to the same class
(which I didn't implement and whose code I don't want to modify)
Now I'd like to change one method for one object only (after it has
been created) without adding any overhead
to the call of the other object's methods.
Is this possible?
Yes.
If the class is a new-style one [1], it just requires invoking the
descriptor protocol by yourself to get a bound method, ie:
>>> class A(object):
... def foo(self): return "original %s" % self
...
>>> a = A()
>>> b = B()
>>> def new_foo(self): return "modified %s" % self
...
>>> b.foo = new_foo.__get__(b, type(b))
>>> b.foo()
'modified <__main__.B instance at 0xb7c0ce4c>'
>>>
If it's a classic class, you can get by using either new.instancemethod
or types.MethodType:
>>> class B:
... def bar(self): return "bar %s" % self
...
>>> a = B()
>>> b = B()
>>> def new_bar(self): return "new bar %s" % self
...
>>> import new
>>> b.bar = new.instancemethod(new_bar, b, type(b))
>>> b.bar()
'new bar <__main__.B instance at 0xb7c0c4ec>'
>>> a.bar()
'bar <__main__.B instance at 0xb7c0c74c>'
>>> import types
>>> b.bar = types.MethodType(new_bar, b, type(b))
>>> b.bar
<bound method instance.new_bar of <__main__.B instance at 0xb7c0c4ec>>
>>> b.bar()
'new bar <__main__.B instance at 0xb7c0c4ec>'
>>> a.bar()
'bar <__main__.B instance at 0xb7c0c74c>'
>>>
Note that using either new.instancemethod or types.MethodType will also
work with new-style classes - it just requires an additional import !-)
[1] for a new style class, type(cls) will return type. For a "classic"
class, type(cls) will return classobj.
HTH
(snip)
P.S. I guess, that there is a computer science term for what I try to
achieve.
If anybody knew it I would be interested to learn it as well.
I don't know of any "official" cs term for this. In prototype-based
OOPL's, setting attributes on a per-object basis is just ordinary
programming. Python is class-based, but on some (if not a lot) of
aspects it's quite close to prototype-based languages.
An unofficial cs term is "monkeypatching". It's usually understood as a
per-class or per-module replacement, but is still appropriate for a
per-object replacement (or addition FWIW).
--
http://mail.python.org/mailman/listinfo/python-list