Decorators using instance variables
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Tue Aug 26 16:52:59 EDT 2008
Bruno Desthuilliers a écrit :
> robert2821 a écrit :
(snip - sorry, hit the 'send' button too soon)
>> def getdec(f):
>> dec = decorator(f)
>> return dec.docall
>>
>
>> class decorator:
>> def __init__ (self, f):
>> self.f = f
>>
>> def docall (self, *a):
>> return self.f(*a)
>>
>> class test:
>> @getdec
>> def doit (self, message):
>> print message
>>
>> if __name__ == '__main__':
>> foo = test ()
>> foo.doit ('Hello, world')
>>
>>> I'm wondering if the following program should work. I think it
>>> should print 'Hello, World', but instead it produces a
>>> TypeError. Is this a bug in decorators, a feature of them, or a
>>> mistake or misunderstanding on my part?
<ot>
Last point : post the whole error message and traceback if possible
</ot>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/tmp/python-10426amG.py", line 19, in <module>
foo.doit ('Hello, world')
File "/usr/tmp/python-10426amG.py", line 10, in docall
return self. f(*a)
TypeError: doit() takes exactly 2 arguments (1 given)
This has to do with how Python makes methods from functions. Your getdec
function - which is the real decorator - returns a class instance, not
another function. This actually prevents doit() to be wrapped in a
method when looked up on a test instance, so doit doesn't receive the
instance as first param (hence the error message).
Here's a working version of your code using new-style classes:
def getdec(f):
dec = Decorator(f)
return dec
class Decorator(object):
def __init__ (self, f):
self.f = f
self.instance = None
def __get__(self, instance, cls):
self.instance = instance
return self
def __call__(self, *args):
args = (self.instance,) + args
return self.f(*args)
class Test(object):
@ getdec
def doit(self, message):
print message
if __name__ == '__main__':
foo = Test ()
FWIW, note that the getdec function here is useless - you'd have the
same result directly applying the Decorator class as a decorator.
HTH
More information about the Python-list
mailing list