我正在处理一个邮件发送库,我希望能够捕获发件人(SMTP,Google AppEngine等)产生的异常,并将它们包含在特定于我的库(ConnectionError,MessageSendError等)的容易捕获的异常中. .),原始的回溯完好无损,因此可以进行调试.在Python 2中执行此操作的最佳方法是什么?
And*_*Dog 26
最简单的方法是使用旧的跟踪对象重新加载.以下示例显示了这一点:
import sys
def a():
def b():
raise AssertionError("1")
b()
try:
a()
except AssertionError: # some specific exception you want to wrap
trace = sys.exc_info()[2]
raise Exception("error description"), None, trace
Run Code Online (Sandbox Code Playgroud)
有关这三个参数的详细信息,请查看raise语句的文档.我的例子将打印:
Traceback (most recent call last):
File "C:\...\test.py", line 9, in <module>
a()
File "C:\...\test.py", line 6, in a
b()
File "C:\...\test.py", line 5, in b
raise AssertionError("1")
Exception: error description
Run Code Online (Sandbox Code Playgroud)
为了完整起见,在Python 3中您将使用raise MyException(...) from e
语法.
raise_from
从future.utils
包装中取出使用。
相关示例复制如下:
from future.utils import raise_from
class FileDatabase:
def __init__(self, filename):
try:
self.file = open(filename)
except IOError as exc:
raise_from(DatabaseError('failed to open'), exc)
Run Code Online (Sandbox Code Playgroud)
在该包中,raise_from
实现如下:
def raise_from(exc, cause):
"""
Equivalent to:
raise EXCEPTION from CAUSE
on Python 3. (See PEP 3134).
"""
# Is either arg an exception class (e.g. IndexError) rather than
# instance (e.g. IndexError('my message here')? If so, pass the
# name of the class undisturbed through to "raise ... from ...".
if isinstance(exc, type) and issubclass(exc, Exception):
e = exc()
# exc = exc.__name__
# execstr = "e = " + _repr_strip(exc) + "()"
# myglobals, mylocals = _get_caller_globals_and_locals()
# exec(execstr, myglobals, mylocals)
else:
e = exc
e.__suppress_context__ = False
if isinstance(cause, type) and issubclass(cause, Exception):
e.__cause__ = cause()
e.__suppress_context__ = True
elif cause is None:
e.__cause__ = None
e.__suppress_context__ = True
elif isinstance(cause, BaseException):
e.__cause__ = cause
e.__suppress_context__ = True
else:
raise TypeError("exception causes must derive from BaseException")
e.__context__ = sys.exc_info()[1]
raise e
Run Code Online (Sandbox Code Playgroud)
这个答案可能有点晚了,但是您可以将函数包装在python 装饰器中。
这是一个关于不同装饰器如何使用的简单备忘单。
以下是一些如何执行此操作的示例代码。只需更改即decorator
可以您需要的不同方式捕获不同的错误。
def decorator(wrapped_function):
def _wrapper(*args, **kwargs):
try:
# do something before the function call
result = wrapped_function(*args, **kwargs)
# do something after the function call
except TypeError:
print("TypeError")
except IndexError:
print("IndexError")
# return result
return _wrapper
@decorator
def type_error():
return 1 / 'a'
@decorator
def index_error():
return ['foo', 'bar'][5]
type_error()
index_error()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7873 次 |
最近记录: |