On Aug 21, 9:22 pm, robert2821 <[EMAIL PROTECTED]> wrote: > 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. -- http://mail.python.org/mailman/listinfo/python-list