voodoo: modifying class methods a posteriori
hungjunglu at yahoo.com
hungjunglu at yahoo.com
Tue Sep 18 14:00:32 EDT 2001
Hi,
This is a problem that has bugged me for a while, now. (Related topic
might be "function closure", which I don't understand much.)
What follows is pure Python voodoo. But when voodoo is used properly,
it does wonders. :)
Say, you have a class "A" with method "f(self)" (which potentially
could be the constructor __init__() or destructor __del__(), by the
way.)
Instance-bound methods can be overriden easily. (I am not interested
in derived subclass, see the reason a bit later.)
class A:
def f(self):
print 'hello'
def g(self):
print 'bye'
a = A()
a.f()
import new
a.f = new.instancemethod(g, a, A)
a.f()
The class-bound method f() can be overriden, easily, too:
class A:
def f(self):
print 'Hello'
def g(self):
print 'Bye'
a = A()
a.f()
A.f.im_func.func_code = g.func_code
a.f()
Now, all that is nice. BUT, usually, when you override a method, you
probably want to do just a bit more than what the old method was
doing. Say, you may only want to add a print statement when the
method is called, or you may want to insert a statement to the
constructor/destructor so object instances can automatically
register/deregister to a particular event handler.
When you have many subclasses derived from subclasses of other
classes, especially when you don't have access to the source code for
one reason or another, or when you don't want to or you can't modify
the source code of the superclass, is there a way of inserting
statements into the class methods?
In derived class, what you would do is something like:
class A:
def f(self):
print 'Hello'
class AA(A):
def f(self):
print 'before saying Hello'
A.f(self)
print 'after saying Hello'
a = AA()
a.f()
Notice you are able to insert statements before and after the base
class method call.
Is there a way of doing the same thing without subclassing?
=============
hmm.... I think I just answered myself, I'll post it to the mailing
list anyway:
class A:
def f(self):
print 'Hello'
def g(self):
print 'before saying Hello'
self.f_old()
print 'after saying Hello'
a = A()
a.f()
import new
A.f_old = A.f
A.f = new.instancemethod(g, None, A)
a.f()
=====================
Wow! It's fun! I wonder why people are still using Java. :)
Hung Jung
More information about the Python-list
mailing list