只捕获直接由导入引起的导入错误
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)
我有这样一种情况,其中 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)