I want to implement the decorator pattern in Python, and I wondered if there is a way to write a decorator that just implements the function it wants to modify, without writing boiler-plate for all the functions that are just forwarded to the decorated object. Like so:
class foo(object):
def f1(self):
print "original f1"
def f2(self):
print "original f2"
class foo_decorator(object):
def __init__(self, decoratee):
self._decoratee = decoratee
def f1(self):
print "decorated f1"
self._decoratee.f1()
def f2(self): # I would like to leave that part out
self._decoratee.f2()
I would like to have calls to foo_decorator.f2
forwarded to decoratee.f2
automatically. Is there a way to write a generic method that forwards all unimplemented function-calls to decoratee
?
To complement @Alec Thomas reply. I modified his answer to follow the decorator pattern. This way you don't need to know the class you're decorating in advance.
Then, you can use it as:
In Python 3, Philipp's accepted answer raised
RuntimeError: maximum recursion depth exceeded
.The way that worked for me:
The workaround is inspired by Ned Batchelder's blog
The UML diagram in the linked Wikipedia article is wrong and so is your code.
If you follow the "decorator pattern", the decorator class is derived from the base decorated class. (In the UML diagram an inheritance arrow from the WindowDecorator to Window is missing).
with
you don't need to implement undecorated methods.
BTW: In strong typed languages there is one more reason, why the decorator must be derived from the decorated class: Otherwise you wouldnt be able to chain decorators.
In one of my projects, I also needed to do one particular thing, that is that even the underlying object should actually execute the method that was reimplemented in the decorator. It is actually quite easy to do if you know where to target it.
The use case is:
It is possible to reach this behaviour like this:
This may not work out of the box as I typed everything else apart from the getattr method from top of my head.
The code looks up the requested attribute in the decorated object, and if it is a method (doesn't work for properties now, but the change to support them should not be too difficult), the code then pulls the actual function out of the method and using the descriptor interface invocation it "rebinds" the function as a method, but on the decorator. Then it is returned and most likely executed.
The effect of this is that if
b
ever callsa
on the original object, then when you have the object decorated and there is any method call coming from the decorator, the decorator makes sure that all methods accessed are bound to the decorator instead, therefore looking up things using the decorator and not the original object, therefore the methods specified in the decorator taking precedence.P.S.: Yes I know it looks pretty much like inheritance, but this done in the sense of composition of multiple objects.
It's arguably not the best practice, but you can add functionality to instances, as I've done to help transition my code from Django's ORM to SQLAlachemy, as follows:
As an addendum to Philipp's answer; if you need to not only decorate, but preserve the type of an object, Python allows you to subclass an instance at runtime:
This is a bit more involved than strictly necessary for your example, where you know the class being decorated in advance.
This might suffice: