You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Monkey Patch修改模块内被类调用的函数以改变类的行为?

如何通过Monkey Patch修改模块内被类调用的函数以改变类的行为?

我来帮你解决这个问题~你遇到的核心问题是找错了要patch的对象位置,咱们一步步来理清楚:

为什么你的尝试没成功?

  1. 第一种patch方式:你修改的是my_library._do_something,但foo类的bar方法里调用的是**_module.py模块内部**的_do_something,不是my_library命名空间里的这个引用,所以根本没影响到类的调用逻辑。
  2. 第二种导入方式:因为你的__init__.py只导出了foo,没有把_do_something暴露出来,所以直接从my_library导入它肯定会报错。

正确的Monkey Patch方法

你需要直接找到函数实际定义的那个模块(也就是my_library._module),然后修改该模块里的函数引用,这样类调用时才会使用新的函数。具体代码如下:

# 导入内部模块
import my_library._module

# 替换模块内的_do_something函数
my_library._module._do_something = lambda: print('goodbye')

# 再创建foo实例调用方法
a = my_library.foo()
a.bar()  # 现在会输出'goodbye'

或者也可以这样写,更直观:

from my_library._module import foo
import my_library._module as inner_module

# 注意:必须修改模块命名空间里的函数,不能只改局部变量
inner_module._do_something = lambda: print('goodbye')

a = foo()
a.bar()  # 输出'goodbye'

原理说明

模块里的类在引用同模块的函数时,是直接绑定到模块的命名空间上的。你之前修改的要么是外部命名空间的引用,要么是局部变量,都没触达类实际依赖的那个模块内的函数对象。只有修改函数所在模块的命名空间中的对应变量,才能让类的调用逻辑切换到新函数。

对应到你的sklearn场景

针对你提到的sklearn.mixture.GaussianMixture和_estimate_gaussian_parameters的情况,逻辑完全一致:

  • 先找到_estimate_gaussian_parameters实际定义的模块(比如它可能在sklearn.mixture._gaussian_mixture这类内部模块里)
  • 导入那个内部模块,然后patch该模块里的_estimate_gaussian_parameters函数
  • 之后创建GaussianMixture实例时,它的方法就会使用你修改后的函数了

备注:内容来源于stack exchange,提问作者leoneu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 10:28:07