当decorator机制是类时,类成员上的Python decorator失败
在创建用于类方法的装饰器时,当装饰器机制是类而不是函数/闭包时,我遇到了问题。当使用类表单时,我的decorator不会被视为绑定方法 一般来说,我更喜欢为装饰器使用函数形式,但在这种情况下,我必须使用现有的类来实现我所需要的 这似乎与函数形式有关,但为什么它对函数形式工作得很好呢 这是我能做的最简单的例子来说明一切。抱歉,代码量太大:当decorator机制是类时,类成员上的Python decorator失败,python,decorator,Python,Decorator,在创建用于类方法的装饰器时,当装饰器机制是类而不是函数/闭包时,我遇到了问题。当使用类表单时,我的decorator不会被视为绑定方法 一般来说,我更喜欢为装饰器使用函数形式,但在这种情况下,我必须使用现有的类来实现我所需要的 这似乎与函数形式有关,但为什么它对函数形式工作得很好呢 这是我能做的最简单的例子来说明一切。抱歉,代码量太大: def decorator1(dec_param): def decorator(function): print 'decorator
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)
输出:
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)
decorator1装饰:
装饰师2装饰:
WrapperClass.\uuuuu init\uuuuu函数=dec\u参数=456
装饰师1装饰:
装饰师2装饰:
WrapperClass.\uuuuu init\uuuuu函数=dec\u参数=456
==成员1====
包装器(,11))dec_param=123
测试成员1(,11)
==成员2====
WrapperClass.\uuuuuuuuuuuuuuuuu(,(22,))dec\u param=456
Test.member2(22,2)您的包装类
需要是一个描述符(就像函数一样!),也就是说,提供适当的特殊方法\uuuuuuuu get\uuuuu
和\uu set\uuu
。教你所有需要知道的 我建议把这个问题改名。实际上,这与decorator并没有真正的关系,而是关于添加一个函数对象作为一个类方法。一般来说(虽然不总是),当问题那么长时,可以通过隔离问题来简化它。例如,如果您尝试手动注释该类,您会意识到它与decorators无关,并且可能比键入所有代码更快