Python:猴子补丁,同一模块中类使用的函数

Python: monkey patch a function used by classes in the same module

提问人:leoneu 提问时间:10/20/2023 更新时间:10/21/2023 访问量:63

问:

我想修改模块中的函数(而不是方法),以便同一模块中使用该函数的类的行为不同。

为简单起见,假设我有一个名为 的文件,以及一个位于名为 ._module.py__init__.pymy_library

# file _module.py
def _do_something():
    print('hello')

class foo():
    def bar(self):
        _do_something()
# file __init__.py
from ._module import foo

我试过像这样给猴子打补丁_do_something

import my_library
my_library._do_something = lambda: print('goodbye')
a = my_library.foo()
a.bar()

但它仍然输出.我还尝试了以下方法hello

from my_library import foo, _do_something
_do_something = lambda: print('goodbye')
a = foo()
a.bar()

但它抛出了一个错误。cannot import name '_do_something' from 'my_library'


如何修改以在调用时反映更改?_do_somethingfoo.bar


PS:实际上我想更改 使用的函数,并且两者都位于同一个文件中。但我认为这与这个问题无关。_estimate_gaussian_parameterssklearn.mixture.GaussianMixture

python-module monkeypatching

评论


答:

1赞 Tranbi 10/21/2023 #1

您应该修补 _module 的功能,而不是导入的功能:my_library

import my_library
my_library._module._do_something = lambda: print('goodbye')
a = my_library.foo()
a.bar()

我还建议使用(请参阅补丁文档):unittest.mock

import my_library
from unittest.mock import patch

with patch.object(my_library._module, '_do_something', lambda: print('goodbye')):
    a = my_library.foo()
    a.bar()

评论

0赞 leoneu 10/21/2023
Verey 彻底回答,谢谢。
1赞 Erdit 10/21/2023 #2

如果你想修改函数,你必须确保你直接在它所在的确切模块中修改函数。_do_something

您尝试的问题是您正在尝试修改导入模块中的函数,但该方法引用了 中的原始函数。my_libraryfoo.bar_do_something_module.py

import my_library

# Monkey patch the function in the module where its from
my_library._module._do_something = lambda: print('goodbye')

a = my_library.foo()
a.bar() #'goodbye'

请注意,在上面的代码中,我们如何直接访问 _module.py 中的函数。这是关键!

评论

0赞 leoneu 10/21/2023
谢谢yiu,这很有帮助。