gpt4 book ai didi

python - 基于类的装饰器和 repr() 保护

转载 作者:太空宇宙 更新时间:2023-11-03 13:45:10 24 4
gpt4 key购买 nike

我试图让我的基于类的装饰器保持原始包装函数的 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() 调用。

再次使用函数工具:

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() 调用装饰器的结果)功能)?

最佳答案

特殊方法是always looked up on the type of the instance (这里是类对象),而不是实例。否则,当您尝试打印类本身的表示时,将使用类上的 __repr__type(class).__repr__(class) 会使用正确的魔法方法,而 class.__repr__() 会引发异常,因为 self 是未提供。

实现你自己的 __repr__ 钩子(Hook):

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)

例如仍然复制 __module____name____doc__ 属性,并复制函数 __dict__ 中的属性,但是使任何特殊方法成为代理。

关于python - 基于类的装饰器和 repr() 保护,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21762517/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com