On Aug 21, 9:22*pm, robert2821 <robert2...@verizon.netwrote:
Hi,
I'm new; greetings all!
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?
TIA, *Bob
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')
*Dec.py
< 1KViewDownload
Have a look at this and fiddle with it:
from types import MethodType
class decorator(object):
def __init__ (self, f):
self. f = f
def docall (self, *a):
print a
return self. f (*a)
def __get__( self, instance, owner ):
print 'in __get__', instance, owner
if instance is not None:
return MethodType( self.docall, instance )
return self.f
class test:
@ decorator
def doit (self, message):
print message
if __name__ == '__main__':
foo = test ()
print test.doit
print foo.doit
foo. doit ('Hello, world')
Output:
in __get__ None __main__.test
<function doit at 0x00A01170>
in __get__ <__main__.test instance at 0x009FEE18__main__.test
<bound method ?.docall of <__main__.test instance at 0x009FEE18>>
in __get__ <__main__.test instance at 0x009FEE18__main__.test
(<__main__.test instance at 0x009FEE18>, 'Hello, world')
Hello, world
The reason is that in the first version, the type of test.doit is
InstanceType, and Python only 'binds' objects of type FunctionType to
MethodType. MethodType is the type that contains an implicit first
'self' parameter. If 'doit' has a __get__ attribute, it is called
whenever -class-.doit or -instance-.doit are accessed, and it returns
a bound method, or something else it likes.
A little more investigating reveals:
>>def f(): pass
...
>>dir( f )
['__call__', '__class__', '__delattr__', '__dict__', '__doc__',
'__get__', '__ge
tattribute__', '__hash__', '__init__', '__module__', '__name__',
'__new__', '__r
...
functions have a '__get__' attribute to perform this very thing.