首页 > 解决方案 > 如何创建一个返回另一个模块的python模块

问题描述

我正在尝试制作 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+ 一起使用的代码,这很可能需要不同的逻辑,但是一旦我让它适用于一个版本,应该不会太难为其他版本找到类似的方法。

标签: pythonpython-importpython-module

解决方案


这实际上是微不足道的。只需替换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这是有效的,因为导入机制正在积极地启用这个 hack,并且作为它的最后一步,在加载它之后将实际模块拉出 。(这绝非偶然。该 hack 是很久以前提出的,我们决定我们很喜欢在进口机器中支持它。)

来自 GvR:https ://mail.python.org/pipermail/python-ideas/2012-May/014969.html


推荐阅读