假设我有一个这样的模块文件:
# my_module.py
print("hello")
然后我有一个简单的脚本:
# my_script.py
import my_module
这将打印"hello"
.
假设我想“覆盖”该print()
函数,以便它返回"world"
。我如何以编程方式执行此操作(无需手动修改my_module.py
)?
我的想法是我需要以某种方式my_module
在导入之前或同时修改源代码。Obvisouly,导入它后我无法执行此操作,因此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)
请提供任何帮助。