voodoo: modifying class methods a posteriori
slinkp23 at yahoo.com
Wed Sep 19 07:49:13 CEST 2001
On Tue, 18 Sep 2001 18:00:32 -0000, hungjunglu at yahoo.com wrote:
>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
>Is there a way of doing the same thing without subclassing?
This is exactly what the Decorator design pattern is for. Note: I
only just learned about Decorators today, so don't take this as gospel
- I may have misunderstood something. But the following seems to work,
it satisfies the criteria of the Decorator as I understand it, and it
does exactly what you're asking for:
"""An abstract Decorator class based on one posted to comp.lang.python
by Rainer Deyke.
def __init__(self, decorated):
self._decorated = decorated
def __getattr__(self, name):
return getattr(self._decorated, name)
def __call__(self, *args, **kwargs):
# Override other operators too.
print "before saying something"
print "after saying something"
self.foo = "I am an attribute of A."
print 'Hello from A.f()'
# Now let's test it.
a = MyDecorator(A())
# Note that a now behaves identically to an instance of A in
# all respects, except that we've "decorated" one method.
# end script
Here's the output that produces:
before saying something
Hello from A.f()
after saying something
I am an attribute of A.
Note a couple of things that make this really cool:
1) you can use any number of decorators chained together in any
a = Decorator1(Decorator2(Decorator3(A())))
Since you'll get different results depending on what order you put the
decorators in, defining 3 decorators gives you ... uh... 15 unique
combinations of 1 to 3 decorators. Compare that to making 15
subclasses of A to get the same flexibility.
2) you can use the same decorators for any number of different objects
as long as they provide the method(s) you're decorating.
More information about the Python-list