Decorating class member functions
Peter Otten
__peter__ at web.de
Fri May 4 00:34:06 EDT 2007
Andy Terrel wrote:
> Okay does anyone know how to decorate class member functions?
>
> The following code gives me an error:
>
> Traceback (most recent call last):
> File "decorators2.py", line 33, in <module>
> s.update()
> File "decorators2.py", line 13, in __call__
> retval = self.fn.__call__(*args,**kws)
> TypeError: update() takes exactly 1 argument (0 given)
>
> ------------------
>
>
> #! /usr/bin/env python
>
> class Bugger (object):
> def __init__ (self, module, fn):
> self.module = module
> self.fn = fn
>
> def __call__ (self,*args, **kws):
> ret_val = self.fn(*args,**kws)
> return ret_val
>
> def instrument (module_name):
> ret_val = lambda x: Bugger(module_name, x)
> return ret_val
>
> class Stupid:
> def __init__(self):
> self.val = 1
>
> @instrument("xpd.spam")
> def update(self):
> self.val += 1
>
>
> s = Stupid()
> s.update()
The problem is not that you are decorating a method but that you are trying
to use a callable class instance as a method. For that to work the class
has to implement the descriptor protocol, see
http://users.rcn.com/python/download/Descriptor.htm
class Bugger (object):
def __init__ (self, module, fn, instance=None):
self.module = module
self.fn = fn
self.instance = instance
def __call__ (self, *args, **kws):
print "calling %s.%s()" % (self.module, self.fn.__name__)
if self.instance is not None:
args = (self.instance,) + args
ret_val = self.fn(*args, **kws)
return ret_val
def __get__(self, instance, class_):
if instance is None:
return self
return Bugger(self.module, self.fn, instance)
def instrument (module_name):
ret_val = lambda x: Bugger(module_name, x)
return ret_val
class Stupid(object):
@instrument("xpd.spam")
def update(self):
print "update()"
s = Stupid()
s.update()
Stupid.update(s)
Peter
More information about the Python-list
mailing list