Python 在同一模块中为类的使用的函数打monkey补丁

Python 在同一模块中为类的使用的函数打monkey补丁

问题描述

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

为了简单起见,假设我有一个名为_module.py的文件和一个名为__init__.py的文件,它们放置在名为my_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_something,以便在调用foo.bar时反映出更改?

附言:实际上,我想修改sklearn.mixture.GaussianMixture使用的_estimate_gaussian_parameters函数,而且两者都在同一个文件中。但我认为这与问题无关。

解决方案

你应该修补_module中的函数,而不是my_library中导入的那个:

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

此外,我建议使用unittest.mock(有关patch的文档,请参阅文档):

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()

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程