简体   繁体   English

如何在给定名称列表的情况下导入模块?

[英]How to import modules given a list of their names?

I am trying to import modules from a list.我正在尝试从列表中导入模块。 This would be to allow easier editing of imported modules, cleaner error message, and better error handling.这将允许更轻松地编辑导入的模块、更清晰的错误消息和更好的错误处理。 Here is basically what I am trying to do:这基本上是我想要做的:

imports = ['sys', 'itertools', 'datetime', 'os']
for x in imports:
    try:
        import x
        print "Successfully imported ", x, '.'
    except ImportError:
        print "Error importing ", x, '.'

The issue here is that it tries importing x, not the value x should hold.这里的问题是它尝试导入 x,而不是 x 应该保持的值。 I realize that to import from the list I could do something like below, but I do not see a way to handle the errors with it:我意识到要从列表中导入,我可以执行以下操作,但我看不到用它处理错误的方法:

imports = ['sys', 'itertools', 'datetime', 'os']
modules = map(__import__, imports)

Is there a way to integrate the error handling with this method or should I try a different approach?有没有办法将错误处理与此方法集成,或者我应该尝试不同的方法?

Instead of mapping them to ___import__ all at once, just append each module to the list modules one at a time inside the for-loop:而不是一次将它们映射到___import__ ,只需在 for 循环中一次一个地将每个模块附加到列表modules中:

imports = ['sys', 'itertools', 'datetime', 'os']
modules = []
for x in imports:
    try:
        modules.append(__import__(x))
        print "Successfully imported ", x, '.'
    except ImportError:
        print "Error importing ", x, '.'

Note however that most Python programmers prefer the use of importlib.import_module rather than __import__ for this task.但是请注意,大多数 Python 程序员更喜欢使用importlib.import_module而不是__import__来完成此任务。


Note too that it might be better to make modules a dictionary instead of a list:还要注意,将modules制作成字典而不是列表可能会更好:

imports = ['sys', 'itertools', 'datetime', 'os']
modules = {}
for x in imports:
    try:
        modules[x] = __import__(x)
        print "Successfully imported ", x, '.'
    except ImportError:
        print "Error importing ", x, '.'

Now, instead of by index:现在,而不是按索引:

modules[0].version
modules[3].path

you can access the modules by name:您可以按名称访问模块:

modules["sys"].version
modules["os"].path

None of the most voted options worked for me.投票最多的选项都不适合我。 They seemed to be imported successfully, but I couldn't use them later.好像导入成功了,但是后来我用不了了。 In case you experienced the same issue, this tutorial solved it for me.如果您遇到同样的问题, 本教程为我解决了它。

modules = ['sys', 'itertools', 'datetime', 'os']  

for lib in modules:
    globals()[lib] = __import__(lib)

PS: I guess they were not added to my global variables before PS:我猜他们之前没有添加到我的全局变量中

you can import programatically achieving the same effect as import module as module_shortname by using globals() :您可以使用globals()以编程方式导入与import module as module_shortname相同的效果:

packages_to_import = [{'name': 'numpy', 'as': 'np'},
                      {'name': 'pandas', 'as': 'pd'}]

for package in packages_to_import:
    package_name = package['name']
    import_as = package.get('as', package_name)

    globals()[import_as] = __import__(package_name)

print(np.version.full_version)
print(pd.__version__)

This worked for me on Python 3.7这在 Python 3.7 上对我有用

modules = ["sys","os","platform","random","time","functools"]

for library in modules:
try:
    exec("import {module}".format(module=library))
except Exception as e:
    print(e)
print(sys.argv)

Importing a submodule:导入子模块:

modules = ["PyQt5"] # pip install PyQt5
submodules = ["QtCore"]

for library in modules:
    for sublibrary in submodules:
        try:
            exec("from {m} import {s}".format(m=library, s=sublibrary))
        except Exception as e:
            print(e)
print(dir()) # Includes QtCore
print(dir(QtCore)) # All functions, classes and variables are exactly correct as with "from PyQt5 import QtCore"

Importing everything:导入所有内容:

modules = ["sys","os","platform","random","time","functools"]
for library in modules:
    try:
        exec("from {module} import *".format(module=library))
    except Exception as e:
        print(e)
print(dir()) # Exactly working as thought

Importing a instance or something:导入实例或其他东西:

modules = ["PyQt5"] # pip install PyQt5
submodules = ["QtCore"]
func = ["QCoreApplication"]
for library in modules:
    for f in func:
        for sublibrary in submodules:
            try:
                exec("from {m}.{s} import {f}".format(m=library, s=sublibrary, f=f)) 
            except Exception as e:
                print(e)
print(dir()) # Includes QCoreApplication instance

Importing everything from a modules's submodule:从模块的子模块中导入所有内容:

modules = ["PyQt5"] # pip install PyQt5
submodules = ["QtCore"]
for library in modules:
    for sublibrary in submodules:
        try:
            exec("from {m}.{s} import *".format(m=library, s=sublibrary)) # Didn't mention f"" strings all the times. But for beginners .format is better.
        except Exception as e:
            print(e)
print(dir()) # Includes all PyQt5.QtCore stuff

You can modify your import x line to use the __import__(x) format您可以修改import x行以使用__import__(x)格式

imports = ['sys', 'itertools', 'datetime', 'os','doesntexit']
for x in imports:
    try:
        __import__(x)
        print "Success"
    except ImportError:
        print "Error ", x

Outputs:输出:

Success
Success
Success
Success
Error  doesntexit

Pesky pseudo submodules讨厌的伪子模块

This works with pesky pseudo submodules like lxml.etree :这适用于像lxml.etree这样的讨厌的伪子模块:

# 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)

Tests:测试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM