gpt4 book ai didi

python - monkeypatching 方法和引用问题

转载 作者:行者123 更新时间:2023-11-28 23:04:46 24 4
gpt4 key购买 nike

我想知道是否有人可以解释并提供解决此问题的方法:

$ cat object-override-methods.py 
class A:
def foo(self):
return 1

class B:
def foo(self):
return 1

for klass in A, B:
orig_foo = klass.foo
def foo(self):
return orig_foo(self) * 2
klass.foo = foo

A().foo()
B().foo()
$ python object-override-methods.py
Traceback (most recent call last):
File "object-override-methods.py", line 15, in <module>
A().foo()
File "object-override-methods.py", line 12, in foo
return orig_foo(self) * 2
TypeError: unbound method foo() must be called with B instance as first argument (got A instance instead)

提前致谢。

最佳答案

orig_foo 是一个全局变量,每次通过循环都会更改值。循环完成后,orig_foo 指向B.foo

内部函数 foo(一个或每个通过循环)在调用时都使用 orig_foo 的全局值。所以他们都调用了 B.foo(self)

当调用像 orig_foo 这样的“未绑定(bind)方法”时,Python2 检查第一个参数是否是适当类的实例。 A().foo() 没有通过这个检查。 (有趣的是,这个检查在 Python3 中被删除了,所以不会引发 TypeError,并且这个错误可能会变得更难找到。)

要解决此问题,您必须将 orig_foo 的值绑定(bind)到适当的 klass。您可以通过将 orig_foo 设为 foo 的局部变量来实现。一种方法是使 orig_foo 成为具有默认值的 foo 的参数。 Python 在定义函数时绑定(bind)默认值。所以 orig_foo=orig_foo 将局部变量 orig_foo 绑定(bind)到 klass.foo 的当前值:

for klass in A, B:
orig_foo = klass.foo
def foo(self, orig_foo=orig_foo):
return orig_foo(self) * 2
klass.foo = foo

关于python - monkeypatching 方法和引用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7205180/

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