[Tutor] class method: dynamic overload/++

Gonçalo Rodrigues op73418 at mail.telepac.pt
Tue Dec 2 10:15:02 EST 2003


On Mon, 1 Dec 2003 14:21:50 -0900, you wrote:

>* Tim Johnson <tim at johnsons-web.com> [031201 13:25]:
>> Hi All:
>>     Is it possible in python to replace (overload)
>> an existing class method with a new one of the same
>> name but with different functionality?
> 
>  Upon review, I could have made myself more clear.
>
>  I should have asked:
>  Is it possible to overload an existing method
>  with another at runtime?
>
>  Hopefully that's clearer
>  -----------------------
> I would welcome pointers to docs and keywords.
> - this is just R & D, not mission critical.
> 
> TIA
> tim
> 

As Gregor Lingl showed, you can replace at runtime one method with
another.

>>> class A(object):
... 	def __init__(self, attrib):
... 		self.attrib = attrib
... 	def method(self):
... 		return self.attrib
... 	
>>> a = A(1)
>>> a.method()
1
>>> def anothermethod(self):
... 	return 2*self.attrib
... 
>>> A.method = anothermethod
>>> a.method()
2
>>> 

What this shows is that *every* instance, even existing ones, will
notice the change (class objects are mutable). Think carefully, if you
are not better served by simple, yet reliable, inheritance:

>>> class B(A):
... 	def method(self):
... 		return 2*self.attrib
... 	
>>> b = B(1)
>>> b.method()
2
>>> 

You can also replace methods in a per-instance base, e.g.

>>> import new
>>> help(new.instancemethod)
Help on class instancemethod in module __builtin__:

class instancemethod(object)
 |  instancemethod(function, instance, class)
 |  
 |  Create an instance method object.
 |  

...

>>> c = A(2)
>>> c.method()
4
>>> c.method = new.instancemethod(lambda self: 3*self.attrib, c, c.__class__)
>>> c.__dict__["method"]
<bound method A.<lambda> of <__main__.A object at 0x010F1EF0>>
>>> c.attrib
2
>>> c.method()
6
>>> a.attrib
1
>>> a.method()
2

As you can see, only the c instance has the new method, not the a
instance.

You can also change the *class* of an instance at run time. This can
fail badly, or, even worse, lead to some disastrous results. Anyway I
mention it for the sake of completion, since in this case there are no
problems:

>>> a.__class__ = B
>>> a.__class__
<class '__main__.B'>
>>> a.method()
2

And Python's dynamic capabilities do not end here. One can go well
into metaclass programming and fashion classes at run time, modify
them, etc.

But at the end of the day, these are all *advanced* techniques and,
unless you are trying to be clever, they are not to be used in the
vast majority of cases. In other words, if you don't know wether you
need them, you don't:

"Metaclasses are deeper magic than 99% of users should ever worry
about. If you wonder whether you need them, you don't (the people who
actually need them know with certainty that they need them, and don't
need an explanation about why). -- Python Guru Tim Peters"

With my best regards,
G. Rodrigues



More information about the Tutor mailing list