问题:从字符串变量导入模块
我正在编写有关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
列表)
请不要建议Sphinx作为其他方法。
回答 0
该__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
您要导入的文件所在的文件夹中没有任何内容,则无法导入任何内容
回答 1
importlib.import_module
是您要寻找的。它返回导入的模块。(仅适用于Python> = 2.7或3.x):
import importlib
mymodule = importlib.import_module('matplotlib.text')
之后,您可以访问模块中的任何内容mymodule.myclass
,例如等等。
回答 2
花了一些时间尝试从列表中导入模块,而这正是使线程到达我那里的大部分方式-但是我不了解___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 <,这可行。
回答 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
除了使用importlib
一个,还可以使用exec
方法从字符串变量导入模块。
在这里,我展示了使用combinations
方法从itertools
包中导入方法的示例exec
:
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)