我试图让我的基于类的装饰器保持repr()
原始包装函数的行为(以匹配functools.wraps
装饰器在函数上的工作方式)。我正在使用 python 3.3。
首先我尝试了functools:
import functools
class ClassBasedDecorator():
def __init__(self, fn):
self.fn = fn
functools.update_wrapper(self, fn)
def __call__(self, *args, **kwargs):
self.fn(*args, **kwargs)
@ClassBasedDecorator
def wrapped(text):
pass
但是当我调用repr()
装饰函数时,我得到:
>>> repr(wrapped)
'<__main__.ClassBasedDecorator object at 0x2d8860b6850>'
很好,所以我尝试自定义__repr__
我的装饰器的方法,它应该由repr()
.
再次使用 functools:
class ClassBasedDecorator():
def __init__(self, fn):
self.fn = fn
functools.update_wrapper(
self, fn,
assigned=functools.WRAPPER_ASSIGNMENTS + ('__repr__',)
)
def __call__(self, *args, **kwargs):
self.fn(*args, **kwargs)
不会改变输出,但会发生一些有趣的事情:
>>> repr(wrapped)
'<__main__.ClassBasedDecorator object at 0x2d8860b69d0>'
>>> wrapped.__repr__()
'<function wrapped at 0x2d8860a9710>'
显式设置__repr__
装饰器实例的方法具有相同的效果。
经过多一点测试,我推断出repr(instance)
实际调用instance.__class__.__repr__(instance)
。因此,实例的覆盖__repr__
方法永远不会被调用。
所以这是我的问题:
- 为什么
repr(instance)
调用instance.__class__.__repr__(instance)
而不是instance.__repr__()
?还是我错过了其他东西? - 您将如何将
functools.wraps
基于函数的装饰器完全复制到基于类的装饰器(包括更改repr()
对装饰函数的调用结果)?