matplotlib 从字符串变量导入模块

ssgvzors  于 2022-11-15  发布在  其他
关注(0)|答案(7)|浏览(125)

我正在为嵌套的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列表)
请不要建议狮身人面像作为不同的方法。

zz2j4svz

zz2j4svz1#

__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,你就不能导入任何东西(在决定是否要保留文件以实现向后兼容之前,请参见caveats,例如与pytest兼容)。
brccelvz

brccelvz2#

importlib.import_module是您要查找的内容。它返回导入的模块。

import importlib

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

此后,您可以访问模块中的任何内容,如text.myclasstext.myfunction等。

a5g8bdjr

a5g8bdjr3#

我花了一些时间尝试从列表中导入模块,这是我大部分时间的思路--但是我没有掌握___import____的用法--
下面是如何从字符串导入模块,并获得与导入相同的行为。还可以尝试/排 debugging 误情况。:)

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〈,这是可行的。

6mzjoqzu

6mzjoqzu4#

除了使用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)
lrpiutwd

lrpiutwd5#

模块自动安装并从列表导入

下面的脚本可以很好地与子模块和pseudo submodules配合使用。

# PyPI imports
import pkg_resources, subprocess, sys

modules   = {'lxml.etree', 'pandas', 'screeninfo'}
required  = {m.split('.')[0] for m in modules}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing   = required - installed

if missing:
    subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--upgrade', 'pip'])
    subprocess.check_call([sys.executable, '-m', 'pip', 'install', *missing])

for module in set.union(required, modules):
    globals()[module] = __import__(module)

测试项目:

print(pandas.__version__)
print(lxml.etree.LXML_VERSION)
mefy6pfw

mefy6pfw6#

我开发了以下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)。

ocebsuys

ocebsuys7#

您还可以使用exec内置函数,将任何字符串作为Python代码执行。

In [1]: module = 'pandas'
   ...: function = 'DataFrame'
   ...: alias = 'DF'

In [2]: exec(f"from {module} import {function} as {alias}")

In [3]: DF
Out[3]: pandas.core.frame.DataFrame

对我来说,这是解决我的问题最具可读性的方法。

相关问题