我试图制作python模块,导入时的行为与另一个模块完全相同。
python>
import foo
import fake_foo
help(foo) == help(fake_foo)
我需要这个,因为我需要在我的fake_foo
模块中添加一些额外的代码mafic代码,它从另一个位置动态加载真实模块。
如果不清楚,下面的代码由于显而易见的原因不起作用:load_source确实返回模块,但它无法告诉python将其加载到当前模块。
# fake_foo/__init__.py
import imp
imp.load_source('foo', '/path/to/foo')
一个非常重要的要求是我无法控制人们如何导入fake_foo
,我无法修改导入的代码,我需要在假模块内部进行整个实现。
PS。我将需要可以使用py27,py35 +的代码,这很可能需要不同的逻辑但是一旦我得到它为一个版本工作就不会太难找到其他版本的类似方法。
这实际上是微不足道的。只需在sys.modules
中替换。
在垫片模块中:
# mod1.py
import sys
import mod2
sys.modules["mod1"] = mod2
在实际模块中:
# mod2.py
var = 'hello'
演示:
>>> import mod1
>>> mod1
<module 'mod2' from 'mod2.py'>
>>> mod1.var
'potato'
这可能看起来很糟糕,但它是Python的一个特性 - 导入机制故意允许这样的技巧。
这是有效的,因为导入机器正在积极地实现这种攻击,并且在加载后,最后一步将实际模块拉出
sys.modules
。 (这不是偶然的。很久以前就提出了黑客攻击,我们决定在进口机械中足够支持它。)
来自GvR:https://mail.python.org/pipermail/python-ideas/2012-May/014969.html