从字符串变量导入模块

Posted

技术标签:

【中文标题】从字符串变量导入模块【英文标题】:import module from string variable 【发布时间】:2012-02-01 21:12:01 【问题描述】:

我正在编写嵌套 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 对上述列表进行 3 种方式的比较:

我不明白 y 对象中加载了什么 - 它是 matplotlib 的基础以及其他内容,但它缺少我想要的信息,即来自 matplotlib.text 包的主要类。它是屏幕截图上的顶部蓝色部分(x 列表)

请不要建议使用 Sphinx 作为不同的方法。

【问题讨论】:

你能解释一下为什么你需要使用__import__(str)而不是标准的import statemetn吗? 这是因为我将处理列表哪些项是 MPL 子模块并获取它们的方法路径 @thesamet - 来吧 - 你想要这个功能的地方有无穷无尽的想法。当您有库的文本配置时,您可以按名称加载它们,这与 import 语句不太匹配。这是一个使用示例:djangosnippets.org/snippets/3048 【参考方案1】:

importlib.import_module 是您正在寻找的。它返回导入的模块。

import importlib

mymodule = importlib.import_module('matplotlib.text')

此后您可以通过mymodule.myclassmymodule.myfunction 等访问模块中的任何内容。

【讨论】:

另一种选择是imp.load_source(..) using the imp module,正如这个答案***.com/questions/67631/…所建议的那样 @gecco 这是针对import moduleName 的,其中moduleName 是字符串。 from moduleName import * 怎么样?【参考方案2】:

除了使用importlib 之外,还可以使用exec 方法从字符串变量中导入模块。

这里我展示了一个使用exec 方法从itertools 包中导入combinations 方法的示例:

MODULES = [
    ['itertools','combinations'],
]

for ITEM in MODULES:
    import_str = "from 0 import 1".format(ITEM[0],', '.join(str(i) for i in ITEM[1:]))
    exec(import_str)

ar = list(combinations([1, 2, 3, 4], 2))
for elements in ar:
    print(elements)

输出:

(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)

【讨论】:

【参考方案3】:

我开发了这 3 个有用的功能:

def loadModule(moduleName):
    module = None
    try:
        import sys
        del sys.modules[moduleName]
    except BaseException as err:
        pass
    try:
        import importlib
        module = importlib.import_module(moduleName)
    except BaseException as err:
        serr = str(err)
        print("Error to load the module '" + moduleName + "': " + serr)
    return module

def reloadModule(moduleName):
    module = loadModule(moduleName)
    moduleName, modulePath = str(module).replace("' from '", "||").replace("<module '", '').replace("'>", '').split("||")
    if (modulePath.endswith(".pyc")):
        import os
        os.remove(modulePath)
        module = loadModule(moduleName)
    return module

def getInstance(moduleName, param1, param2, param3):
    module = reloadModule(moduleName)
    instance = eval("module." + moduleName + "(param1, param2, param3)")
    return instance

每次我想重新加载一个新实例时,我只需要像这样调用 getInstance():

myInstance = getInstance("MyModule", myParam1, myParam2, myParam3)

终于可以调用新实例中的所有函数了:

myInstance.aFunction()

这里唯一的特殊性是自定义实例的参数列表(param1、param2、param3)。

【讨论】:

【参考方案4】:

__import__ 函数可能有点难以理解。

如果你改变了

i = __import__('matplotlib.text')

i = __import__('matplotlib.text', fromlist=[''])

那么i 将引用matplotlib.text

在 Python 2.7 和 Python 3.1 或更高版本中,您可以使用importlib

import importlib

i = importlib.import_module("matplotlib.text")

一些笔记

如果您尝试从子文件夹导入某些内容,例如./feature/email.py,代码看起来像importlib.import_module("feature.email")

如果您尝试导入的文件所在的文件夹中没有__init__.py,您将无法导入任何内容

【讨论】:

importlib 应该在 的 pypi 上可用 适用于从 Google 来到这里的任何人。应该注意的是,如果您尝试从子文件夹(例如,./feature/email.py)导入某些内容,代码将类似于 importlib.import_module("feature.email") 最后,还要记住,如果您要导入的文件所在的文件夹中没有__init__.py,您将无法导入任何内容。 @mzjn 这适用于import moduleName,其中 moduleName 是字符串。 from moduleName import * 怎么样? 刚刚在这里找到了我的问题的答案,以防有人需要***.com/a/31306598/248616【参考方案5】:

花了一些时间尝试从列表中导入模块,这是让我大部分时间到达那里的线程 - 但我没有掌握 ___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

【讨论】:

以上是关于从字符串变量导入模块的主要内容,如果未能解决你的问题,请参考以下文章

从导入模块中的函数访问全局变量

python 模块导入全局变量

导入模块

112.模块导入

112.模块导入

Python模块导入详解