如何对Python库A中的print_函数打补丁以覆盖原有实现?
解决Python函数打补丁不生效的问题
你的问题核心在于:module_B.py里通过from A.C.module_C import print_直接导入了函数对象,这个引用会被存在module_B的命名空间里,后续修改module_C中的print_不会影响已经导入到module_B里的这个引用。再加上A/__init__.py里提前导入了module_B,导致你的补丁打晚了。
下面给你两种可行的修改方案:
方案一:直接替换module_B中的print_引用
既然module_B里已经持有了原始print_的引用,那直接修改这个引用就行:
def _new_print(): print("patched") # 先导入module_B,再替换它里面的print_ from A import module_B module_B.print_ = _new_print module_B.run() # 输出"patched"
方案二:在module_B被加载前完成补丁
因为A/__init__.py会自动导入module_B,所以要避免先导入A,而是直接导入module_C打补丁,再导入module_B(绕过A的__init__):
def _new_print(): print("patched") # 先打补丁 from A.C import module_C module_C.print_ = _new_print # 直接从A.B导入module_B,而不是从A导入,避免触发A/__init__.py里的提前导入 from A.B import module_B module_B.run() # 输出"patched"
补充说明
如果你的场景更复杂(比如涉及多次导入),可以用importlib.reload重新加载module_B,但要注意这种方式可能带来其他依赖问题:
import importlib def _new_print(): print("patched") from A.C import module_C module_C.print_ = _new_print from A import module_B # 重新加载module_B,让它重新导入print_ importlib.reload(module_B) module_B.run() # 输出"patched"
内容的提问来源于stack exchange,提问作者user3391299
相关产品推荐
相关产品推荐

