Python decorators on class members fail when decorator mechanism is a class
当创建用于类方法的装饰器时,当装饰器机制是类而不是函数/闭包时,我遇到了麻烦。使用类窗体时,我的修饰器不会被视为绑定方法。
一般来说,我更喜欢使用修饰符的函数形式,但在本例中,我必须使用现有的类来实现我所需要的。
这看起来似乎与python-decorator-makes-function-forget-that-it-lossed-to-a-class有关,但是为什么它对于函数形式来说工作得很好呢?
这是我能举的最简单的例子来展示所有的进展。对于代码的数量感到抱歉:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 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 ' ====member1====' test.member1(11) print ' ====member2====' test.member2(22) print ' ====free1====' free1(11) print ' ====free2====' free2(22) |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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) |
号
您的