When creating decorators for use in class methods, I have problems when the decorator mechanism is a class and not a function / closure. When a class class is used, my decorator is not considered to be a related method.
I usually prefer to use the function form for decorators, but in this case I have to use an existing class to implement what I need.
It seems like this might be due to python-decorator-makes-function-forget-that-it-belongs-to-a-class , but why is this just fine for the function form?
Here is a simple example that I could do to show everything. Sorry for the amount of code:
def decorator1(dec_param): def decorator(function): print 'decorator1 decoratoring:', function def wrapper(*args): print 'wrapper(%s) dec_param=%s' % (args, dec_param) function(*args) return wrapper return decorator class WrapperClass(object): def __init__(self, function, dec_param): print 'WrapperClass.__init__ function=%s dec_param=%s' % (function, dec_param) self.function = function self.dec_param = dec_param def __call__(self, *args): print 'WrapperClass.__call__(%s, %s) dec_param=%s' % (self, args, self.dec_param) self.function(*args) def decorator2(dec_param): def decorator(function): print 'decorator2 decoratoring:', function return WrapperClass(function, dec_param) return decorator class Test(object): @decorator1(dec_param=123) def member1(self, value=1): print 'Test.member1(%s, %s)' % (self, value) @decorator2(dec_param=456) def member2(self, value=2): print 'Test.member2(%s, %s)' % (self, value) @decorator1(dec_param=123) def free1(value=1): print 'free1(%s)' % (value) @decorator2(dec_param=456) def free2(value=2): print 'free2(%s)' % (value) test = Test() print '\n====member1====' test.member1(11) print '\n====member2====' test.member2(22) print '\n====free1====' free1(11) print '\n====free2====' free2(22)
Exit:
decorator1 decoratoring: <function member1 at 0x3aba30> decorator2 decoratoring: <function member2 at 0x3ab8b0> WrapperClass.__init__ function=<function member2 at 0x3ab8b0> dec_param=456 decorator1 decoratoring: <function free1 at 0x3ab9f0> decorator2 decoratoring: <function free2 at 0x3ab970> WrapperClass.__init__ function=<function free2 at 0x3ab970> dec_param=456 ====member1==== wrapper((<__main__.Test object at 0x3af5f0>, 11)) dec_param=123 Test.member1(<__main__.Test object at 0x3af5f0>, 11) ====member2==== WrapperClass.__call__(<__main__.WrapperClass object at 0x3af590>, (22,)) dec_param=456 Test.member2(22, 2) <<<- Badness HERE! ====free1==== wrapper((11,)) dec_param=123 free1(11) ====free2==== WrapperClass.__call__(<__main__.WrapperClass object at 0x3af630>, (22,)) dec_param=456 free2(22)
python decorator
user203079
source share