区分ImportError是因为找不到模块还是python中模块本身导入错误?

2024-04-27 13:14:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我在python中有几个模块,它们是动态导入的,并且都具有相同的结构(插件.py, 模型.py, 测试.py, ...). 在管理代码中,我想导入这些子模块,但例如模型.py或者测试.py不是强制性的。(所以我可以有plugin_a.plugin和{},但只有plugin_b.plugin)。在

我可以通过以下方式检查子模块是否存在

try:
    __import__(module_name + ".tests")
except ImportError:
    pass

如果找不到module_name+".tests",那么这将失败;但是如果tests-模块本身将尝试导入某个未找到的内容,例如由于键入错误而导致的,则该操作也将失败。 有什么方法可以检查模块是否存在,而不导入它,或者确保ImportError只由一个特定的导入操作引发?在


Tags: 模块代码namepy模型插件方式tests
3条回答

从回溯的长度可以看出导入失败的深度。丢失的.test模块只有一个回溯帧,直接依赖失败有两个帧,等等

Python 2版本,使用^{}访问回溯:

import sys


try:
    __import__(module_name + ".tests")
except ImportError:
    if sys.exc_info()[-1].tb_next is not None:
        print "Dependency import failed"
    else:
        print "No module {}.tests".format(module_name)

Python 3版本,其中exceptions have a ^{} attribute

^{pr2}$

演示:

>>> import sys
>>> def direct_import_failure(name):
...     try:
...         __import__(name)
...     except ImportError:
...         return sys.exc_info()[-1].tb_next is None
... 
>>> with open('foo.py', 'w') as foo:
...     foo.write("""\
... import bar
... """)
... 
>>> direct_import_failure('bar')
True
>>> direct_import_failure('foo')
False

以下来自:How to check if a python module exists without importing it

^{}函数将返回一个3元素元组(file、pathname、description)或引发ImportError。在

如果模块有问题,它不会引发错误,只有在它不存在的情况下。在

python文档建议您首先查找并导入包,然后在第二个find_module中使用它的路径,必要时递归执行。在

我觉得这有点乱。在

下面的函数将检查在任何相对导入级别(module.pypackage.module.pypackage.subpackage.module.py等)上是否存在给定的模块。在

imp.find_module返回一个打开的文件,可以在imp.load_module中使用,但这看起来也有点笨拙,所以我关闭了该文件,以便可以在函数外部导入它。在

请注意,这并不完美。如果您正在寻找package.subpackage.module,但实际上{}是一个有效的模块,它也将返回true。在

import imp
import importlib

def module_exists(modulename):
    modlist = modulename.split('.')
    pathlist = None
    for mod in modlist:
        print mod
        try:
            openfile, pathname, desc = imp.find_module(mod,pathlist)
            pathlist = [pathname]
        except ImportError:
            print "Module '{}' does not exist".format(mod)
            return(False)
        else:
            print 'found {}'.format(openfile)
            if openfile:
                openfile.close()
                return(True)

if __name__ == '__main__':
    mymodule = 'parrot.type.norwegian_blue'
    if module_exists(mymodule):
        importlib.import_module(mymodule)

还请注意,我使用的是importlib.import_module,而不是{}。在

最后,请注意,^{}是Python2.7及更高版本

您知道如果模块不存在,导入错误消息会是什么样子,所以只需检查一下:

try:
    module = module_name + '.tests'
    __import__(module)
except ImportError, e:
    if e.args and e.args[0] == 'No module named ' + module:
        print(module, 'does not exist')
    else:
        print(module, 'failed to import')

相关问题 更多 >