我正在使用其他人编写的模块。我想修补模块中定义的类的 __init__
方法。我发现的展示如何做到这一点的例子都假设我自己会调用这个类(例如 Monkey-patch Python class )。然而,这种情况并非如此。在我的情况下,该类是在另一个模块的函数中初始化的。请参阅下面的(非常简化的)示例:
thirdpartymodule_a.py
class SomeClass(object):
def __init__(self):
self.a = 42
def show(self):
print self.a
thirdpartymodule_b.py
import thirdpartymodule_a
def dosomething():
sc = thirdpartymodule_a.SomeClass()
sc.show()
mymodule.py
import thirdpartymodule_b
thirdpartymodule_b.dosomething()
有什么办法可以修改 SomeClass
的 __init__
方法,以便在从 mymodule.py 调用 dosomething
时,例如,打印 43 而不是 42?理想情况下,我可以包装现有的方法。
我无法更改thirdpartymodule*.py 文件,因为其他脚本依赖于现有功能。我宁愿不必创建自己的模块副本,因为我需要进行的更改非常简单。
编辑 2013-10-24
在上面的示例中,我忽略了一个小而重要的细节。 SomeClass
由 thirdpartymodule_b
导入,如下所示:fromthirdpartymodule_a import SomeClass
。
要执行 F.J 建议的补丁,我需要替换 thirdpartymodule_b
中的副本,而不是 thirdpartymodule_a
。例如thirdpartymodule_b.SomeClass.__init__ = new_init
.
最佳答案
以下应该有效:
import thirdpartymodule_a
import thirdpartymodule_b
def new_init(self):
self.a = 43
thirdpartymodule_a.SomeClass.__init__ = new_init
thirdpartymodule_b.dosomething()
如果您希望新的 init 调用旧的 init,请将 new_init()
定义替换为以下内容:
old_init = thirdpartymodule_a.SomeClass.__init__
def new_init(self, *k, **kw):
old_init(self, *k, **kw)
self.a = 43
关于python - 猴子在Python的另一个模块中修补一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19545982/