Mikael Olofsson <mik...@isy.liu.se> wrote: > George Sakkis decorator function solution seems to work equally well for > functions and methods. However, I prefer the cleaner encapsulation given > by a class. Based on those observations, I think I will use the > following approach: > > >>> class test_decorator(object): > ... _inst = None > ... def __init__(self,func): > ... self._func = func > ... def __call__(self, *args): > ... print 'Decorator:', args > ... if self._inst is None: > ... print 'We seem to be decorating a function.' > ... self._func(*args) > ... else: > ... print 'We seem to be decorating a method.' > ... self._func(self._inst,*args) > ... def __get__(self, inst, cls): > ... self._inst = inst > ... return self > ...
The __get__ method should be returning a new object, NOT modifying the state of the decorator. As written it will break badly and unexpectedly in a variety of situations: >>> inst1 = cls() >>> inst2 = cls() >>> inst1, inst2 (<__main__.cls object at 0x011BC470>, <__main__.cls object at 0x011BCC90>) >>> m = inst1.meth >>> m() Decorator: () We seem to be decorating a method. Method: <__main__.cls object at 0x011BC470> () >>> inst2.meth() Decorator: () We seem to be decorating a method. Method: <__main__.cls object at 0x011BCC90> () >>> m() Decorator: () We seem to be decorating a method. Method: <__main__.cls object at 0x011BCC90> () or even this: >>> inst1.meth(inst2.meth()) Decorator: () We seem to be decorating a method. Method: <__main__.cls object at 0x011BCC90> () Decorator: (None,) We seem to be decorating a method. Method: <__main__.cls object at 0x011BCC90> (None,) -- Duncan Booth http://kupuguy.blogspot.com -- http://mail.python.org/mailman/listinfo/python-list