Max*_*ini 3 python repr decorator python-3.x python-decorators
我试图让我的基于类的装饰器保持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
Run Code Online (Sandbox Code Playgroud)
但是当我调用repr()装饰函数时,我得到:
>>> repr(wrapped)
'<__main__.ClassBasedDecorator object at 0x2d8860b6850>'
Run Code Online (Sandbox Code Playgroud)
很好,所以我试着自定义__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)
Run Code Online (Sandbox Code Playgroud)
不会改变输出,但会发生一些有趣的事情:
>>> repr(wrapped)
'<__main__.ClassBasedDecorator object at 0x2d8860b69d0>'
>>> wrapped.__repr__()
'<function wrapped at 0x2d8860a9710>'
Run Code Online (Sandbox Code Playgroud)
显式设置__repr__装饰器实例的方法具有相同的效果.
经过一些测试后,我推断出了repr(instance)实际调用instance.__class__.__repr__(instance).因此,__repr__永远不会调用实例的overriden 方法.
所以这是我的问题:
repr(instance)打电话instance.__class__.__repr__(instance)而不是instance.__repr__()?还是我错过了别的什么?functools.wraps基于函数的装饰器对基于类的装饰器的作用(包括改变repr()装饰函数调用的结果)?特殊方法总是在实例的类型(这里是类对象)上查找,而不是在实例上查找.否则__repr__,当您尝试打印类本身的表示时,将使用类; type(class).__repr__(class)将使用正确的魔术方法,而class.__repr__()因为self未提供异常会引发异常.
实现自己的__repr__钩子:
class ClassBasedDecorator():
def __init__(self, fn):
self.fn = fn
functools.update_wrapper(self, fn)
def __call__(self, *args, **kwargs):
self.fn(*args, **kwargs)
def __repr__(self):
return repr(self.fn)
Run Code Online (Sandbox Code Playgroud)
例如,仍然复制__module__,__name__和__doc__属性,并从函数复制属性__dict__,但使任何特殊方法成为代理.
| 归档时间: |
|
| 查看次数: |
306 次 |
| 最近记录: |