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
--
http://mail.python.org/mailman/listinfo/python-list