假设我有一个这样的模块文件:
# my_module.py print("hello")
然后我有一个简单的脚本:
# my_script.py import my_module
这将打印"hello"
.
假设我想"覆盖"该print()
函数,以便它返回"world"
.我怎么能以编程方式执行此操作(无需手动修改my_module.py
)?
我想的是我需要以某种方式修改my_module
导入之前或导入时的源代码.显然,我导入后无法执行此操作,因此使用解决方案unittest.mock
是不可能的.
我还以为我可以读取文件my_module.py
,执行修改,然后加载它.但这很难看,因为如果模块位于其他地方,它将无法工作.
我认为,好的解决方案就是利用importlib
.
我阅读了文档,发现了一种非常相互交叉的方法:get_source(fullname)
.我以为我可以覆盖它:
def get_source(fullname): source = super().get_source(fullname) source = source.replace("hello", "world") return source
不幸的是,我对所有这些抽象类有点迷失,我不知道如何正确执行此操作.
我徒劳地试过:
spec = importlib.util.find_spec("my_module") spec.loader.get_source = mocked_get_source module = importlib.util.module_from_spec(spec)
欢迎任何帮助.