Python exception chaining
本问题已经有最佳答案,请猛点这里访问。
在Python中是否有使用异常链的标准方法?像Java异常所引起的?
这是一些背景。
我有一个具有一个主要异常类
1 2 | class DSError(Exception): pass |
在这个模块中的某个地方将有:
1 2 3 4 5 6 7 8 9 | try: v = my_dict[k] something(v) except KeyError as e: raise DSError("no key %s found for %s" % (k, self)) except ValueError as e: raise DSError("Bad Value %s found for %s" % (v, self)) except DSError as e: raise DSError("%s raised in %s" % (e, self)) |
基本上,这个片段应该只抛出dserror并告诉我发生了什么以及为什么。问题是,try块可能会抛出许多其他异常,因此如果我可以执行以下操作,我更愿意这样做:
1 2 3 4 5 | try: v = my_dict[k] something(v) except Exception as e: raise DSError(self, v, e) # Exception chained... |
这是标准的Python疗法吗?我在其他模块中没有看到异常链,那么在Python中是如何做到的呢?
异常链接仅在Python3中可用,您可以在其中写入:
1 2 3 4 | try: v = {}['a'] except KeyError as e: raise ValueError('failed') from e |
产生一个输出
1 2 3 4 5 6 7 8 9 10 11 | Traceback (most recent call last): File"t.py", line 2, in <module> v = {}['a'] KeyError: 'a' The above exception was the direct cause of the following exception: Traceback (most recent call last): File"t.py", line 4, in <module> raise ValueError('failed') from e ValueError: failed |
在大多数情况下,您甚至不需要
1 2 3 4 5 6 7 8 9 10 11 | Traceback (most recent call last): File"t.py", line 2, in <module> v = {}['a'] KeyError: 'a' During handling of the above exception, another exception occurred: Traceback (most recent call last): File"t.py", line 4, in <module> raise ValueError('failed') ValueError: failed |
在python 2中可以做的是向异常类添加自定义属性,比如:
1 2 3 4 5 6 7 8 9 | class MyError(Exception): def __init__(self, message, cause): super(MyError, self).__init__(message + u', caused by ' + repr(cause)) self.cause = cause try: v = {}['a'] except KeyError as e: raise MyError('failed', e) |
这就是你想要的吗?
1 2 3 4 5 6 7 8 9 10 11 12 | class MyError(Exception): def __init__(self, other): super(MyError, self).__init__(other.message) >>> try: ... 1/0 ... except Exception, e: ... raise MyError(e) Traceback (most recent call last): File"<pyshell#27>", line 4, in <module> raise MyError(e) MyError: division by zero |
如果要存储原始的异常对象,当然可以在自己的异常类的
1 2 3 4 | class MyError(Exception): def __init__(self, other): self.traceback = sys.exc_info() super(MyError, self).__init__(other.message) |
之后,您可以访问异常的