使用 "__import__" 从字符串变量导入模块与正常导入语句结果不同

261 投票
7 回答
227105 浏览
提问于 2025-04-17 09:28

我正在为嵌套的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 个回答

6

我花了一些时间尝试从一个列表中导入模块,这个讨论让我走了很大一部分路,但我还是没搞懂如何使用___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及以下版本,这个方法是有效的。

115

importlib.import_module 是你需要的东西。它会返回你导入的模块。

import importlib

# equiv. of your `import matplotlib.text as text`
text = importlib.import_module('matplotlib.text')

之后你可以像这样访问模块里的内容:text.myclasstext.myfunction等等。

354

__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 的兼容性)。

撰写回答