Michele Simionato <michele.simion...@gmail.com> wrote: > On May 12, 8:54 am, Mikael Olofsson <mik...@isy.liu.se> wrote: >> Peter Otten wrote: >> > I usually use decorator functions, but I think the following should >> > wor > k, >> > too: >> >> > class deco(object): >> > def __init__(self, func): >> > self._func = func >> > def __call__(self, *args): >> > print "Decorator:", args >> > self._func(*args) >> > def __get__(self, *args): >> > return deco(self._func.__get__(*args)) >> >> This looks like a winner to me. It is elegant, works for functions as >> well as for methods, and does not mess with the internals of the >> decorator which avoids the problems that Duncan pointed out. > > Still it turns something which is a function into an object and you > lose the > docstring and the signature. pydoc will not be too happy with this > approach.
Also it means every time the decorator is invoked 'self' references a new instance of deco. I don't know why Mikael wants to use a class rather than a function but if he wants to save state between calls this isn't going to help. Something like this may work, and preserves the function name, type and docstring: from functools import wraps class Decorator(object): def __init__(self, func): self._func = func def __new__(cls, func): decorator = object.__new__(cls) decorator.__init__(func) @wraps(func) def wrapper(*args, **kwds): return decorator(*args, **kwds) return wrapper class deco(Decorator): def __init__(self, func): self.calls = 0 Decorator.__init__(self, func) def __call__(self, *args): self.calls += 1 print "Decorator:", args, "called", self.calls, "times" return self._func(*args) class C(object): @deco def meth(self, arg): """meth's docstring""" print "meth %r %r" % (self, arg) return arg+1 inst1 = C() inst2 = C() print repr(inst1.meth), inst1.meth.__doc__ print inst1.meth(5) print inst1.meth(inst2.meth(3)) ------------------- Output: <bound method C.meth of <__main__.C object at 0x00B45390>> meth's docstring Decorator: (<__main__.C object at 0x00B45390>, 5) called 1 times meth <__main__.C object at 0x00B45390> 5 6 Decorator: (<__main__.C object at 0x00B453D0>, 3) called 2 times meth <__main__.C object at 0x00B453D0> 3 Decorator: (<__main__.C object at 0x00B45390>, 4) called 3 times meth <__main__.C object at 0x00B45390> 4 5 -- Duncan Booth http://kupuguy.blogspot.com -- http://mail.python.org/mailman/listinfo/python-list