只捕获直接由导入引起的导入错误

Only Catch Importerrors Caused Directly by Import

我有这样一种情况,其中 python 文件是用 importlib 模块动态加载的。然后我捕获 ImportError 来检测文件是否不存在。然而,这也捕获了由导入间接引起的任何 importerrors 。例如

# file a.py
import importlib

try:
    importlib.load_module("b")
except ImportError:
    print("it seems b.py does not exist!")  # oops! it actually does, it just also raised an ImportError!

# file b.py

import nonexistantmoduletocauserror

我希望能够区分由我的 importlib.load_module 引起的 ImportError 和由执行导入模块本身的过程引起的 ImportError 之间的区别。

只需创建并使用自定义异常:

文件MyImportError.py:

class MyImportError(Exception):
    """Raise for my specific kind of exception"""

文件a.py:

from MyImportError import MyImportError
import importlib

try:
    importlib.import_module("b")
except MyImportError:
    print("Error: It seems b.py does not exist!")

文件b.py:

from MyImportError import MyImportError

try:
    import nonexistantmoduletocauserror
except ImportError:
    raise MyImportError("Error: It seems nonexistantmoduletocauserror.py does not exist!")

编辑:

好的,我明白了,那你换个方式试试:

文件a.py:

import traceback
import sys
import importlib

try:
    importlib.import_module("b")
except ImportError as e:
    exc_type, exc_obj, tb = sys.exc_info()
    print(exc_type)
    print(exc_obj)
    traceback.print_exc()

文件b.py:

import nonexistantmoduletocauserror

您将看到包含相关错误消息的完整回溯:

Traceback (most recent call last):
  File "/Users/darius/code/python/sklearn-keras/examples/a.py", line 8, in <module>
    importlib.import_module("b")
  File "/Users/darius/anaconda2/envs/sklearn-keras/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/Users/darius/code/python/sklearn-keras/examples/b.py", line 3, in <module>
    import nonexistantmoduletocauserror
ImportError: No module named nonexistantmoduletocauserror

<type 'exceptions.ImportError'>
No module named nonexistantmoduletocauserror

load_module() 现在已弃用。他们说改用 exec_module() 。这确实提供了一个解决方案,因为导入现在分两个阶段进行:找到模块,然后执行它。请参阅文档中的 "Checking if a module can be imported",此处:https://docs.python.org/3/library/importlib.html#checking-if-a-module-can-be-imported

在您的情况下,代码如下所示:

spec = importlib.util.find_spec('b')
if spec is None:
    print("it seems b.py does not exist!")
else:
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)