python - 猴子在Python的另一个模块中修补一个类

标签 python class unit-testing monkeypatching

我正在使用其他人编写的模块。我想修补模块中定义的类的 __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

在上面的示例中,我忽略了一个小而重要的细节。 SomeClassthirdpartymodule_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/

相关文章:

c++ - CPP 文件错误中类的重新定义

unit-testing - 在我的单元测试中避免 try...catch...finally... 的最佳方法是什么?

python - 毒性 0% 覆盖率

作为脚本从 shell 运行时,python scrapy 会产生不同的结果

python - 带 basemap 的 Matplotlib 子图动画

c++ - 在类中初始化类

Python 相当于 c++ find_if

c# - 在asp.net中创建一个基本类

unit-testing - "zef test ."返回的结果与使用 raku -Ilib 运行某些测试不同

c# - 接口(interface)和包装器太多?