使用 "__import__" 从字符串变量导入模块与正常导入语句结果不同
我正在为嵌套的matplotlib(MPL)库制作一份个人文档,这份文档和MPL自己提供的文档不一样,主要是针对我感兴趣的子模块包。我正在编写一个Python脚本,希望能自动生成未来MPL版本的文档。
我选择了一些感兴趣的子模块/包,并想列出它们的主要类,然后用这些类生成一个列表,并通过pydoc
进行处理。
问题是,我找不到方法让Python从字符串中加载一个子模块。下面是我尝试的一个例子:
import matplotlib.text as text
x = dir(text)
i = __import__('matplotlib.text')
y = dir(i)
j = __import__('matplotlib')
z = dir(j)
这里是通过pprint对上述列表进行的三方比较:
我不明白y
对象中加载了什么——它是基础的matplotlib
加上一些其他东西,但缺少我想要的信息,也就是来自matplotlib.text
包的主要类。这部分在截图中是蓝色的部分(x
列表)。
7 个回答
我花了一些时间尝试从一个列表中导入模块,这个讨论让我走了很大一部分路,但我还是没搞懂如何使用___import____。
所以这里是如何从一个字符串导入模块的方法,效果和直接使用import是一样的。还有,记得处理错误的情况哦。:)
pipmodules = ['pycurl', 'ansible', 'bad_module_no_beer']
for module in pipmodules:
try:
# because we want to import using a variable, do it this way
module_obj = __import__(module)
# create a global object containging our module
globals()[module] = module_obj
except ImportError:
sys.stderr.write("ERROR: missing python module: " + module + "\n")
sys.exit(1)
没错,对于Python 2.7及以上版本,你有其他选择,但对于2.6及以下版本,这个方法是有效的。
importlib.import_module
是你需要的东西。它会返回你导入的模块。
import importlib
# equiv. of your `import matplotlib.text as text`
text = importlib.import_module('matplotlib.text')
之后你可以像这样访问模块里的内容:text.myclass
、text.myfunction
等等。
__import__
这个函数可能有点难理解。
如果你把
i = __import__('matplotlib.text')
改成
i = __import__('matplotlib.text', fromlist=[''])
那么 i
就会指向 matplotlib.text
这个模块。
在 Python 3.1 或更高版本中,你可以使用 importlib
:
import importlib
i = importlib.import_module("matplotlib.text")
一些注意事项
如果你想从一个子文件夹导入东西,比如
./feature/email.py
,那么代码应该写成importlib.import_module("feature.email")
在 Python 3.3 之前,如果你要导入的文件所在的文件夹里没有
__init__.py
文件,你是无法导入任何东西的(在决定是否保留这个文件以兼容旧版本时,可以查看 一些注意事项,比如与pytest
的兼容性)。