Pythonexception链接

在Python中使用exception链是否有一个标准的方法? 像Javaexception'造成'?

这是一些背景。

我有一个主要exception类DSError模块:

  class DSError(Exception): pass 

在这个模块的某个地方会有:

 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块可能会抛出很多其他exception,所以我宁愿如果我可以做这样的事情:

 try: v = my_dict[k] something(v) except Exception as e: raise DSError(self, v, e) # Exception chained... 

这是标准pythonic方式? 我没有在其他模块中看到exception链,那么在Python中是如何完成的?

exception链接仅在Python 3中可用,您可以在其中编写:

 try: v = {}['a'] except KeyError as e: raise ValueError('failed') from e 

这产生一个输出

 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 

在大多数情况下,你甚至不需要from ; Python 3默认显示exception处理期间发生的所有exception,如下所示:

 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中你可以做的是将自定义属性添加到你的exception类,如:

 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) 

这是你要求的吗?

 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 

如果你想存储原始的exception对象,你当然可以在你自己的exception类的__init__ 。 您可能实际上想要存储回溯,因为exception对象本身不提供有关发生exception的位置的很多有用的信息:

 class MyError(Exception): def __init__(self, other): self.traceback = sys.exc_info() super(MyError, self).__init__(other.message) 

在此之后,您可以访问exception的traceback属性来获取有关原始exception的信息。 (Python 3已经提供这个作为exception对象的__traceback__属性。)