【发布时间】:2020-12-18 16:37:48
【问题描述】:
我正在尝试修补类的 __new__ 方法,但它没有按预期工作。
from contextlib import contextmanager
class A:
def __init__(self, arg):
print('A init', arg)
@contextmanager
def patch_a():
new = A.__new__
def fake_new(cls, *args, **kwargs):
print('call fake_new')
return new(cls, *args, **kwargs)
# here I get error: TypeError: object.__new__() takes exactly one argument (the type to instantiate)
A.__new__ = fake_new
try:
yield
finally:
A.__new__ = new
if __name__ == '__main__':
A('foo')
with patch_a():
A('bar')
A('baz')
我希望得到以下输出:
A init foo
call fake_new
A init bar
A init baz
但在call fake_new 之后出现错误(请参阅代码中的注释)。
对我来说似乎我只是装饰了一个__new__ 方法并传播所有参数不变。
它不起作用,原因对我来说是模糊的。
我也可以写return new(cls) 并调用A('bar') 工作正常。但随后A('baz') 中断。
有人能解释一下是怎么回事吗?
Python 版本为 3.8
【问题讨论】:
-
A.__new__ is object.__new__只接受一个参数。你应该把它简单地称为new(cls)。我不明白为什么与'baz'的通话失败......奇怪......
标签: python python-3.x class