Raising exceptions when an exception is already present in Python 3
当第二个(
1 2 3 4 5 6 7 8 9 10 | class A(Exception): pass class B(Exception): pass try: try: raise A('first') finally: raise B('second') except X as c: print(c) |
如果用
1 2 3 4 5 6 7 8 9 10 11 | Traceback (most recent call last): File"raising_more_exceptions.py", line 6, in raise A('first') __main__.A: first During handling of the above exception, another exception occurred: Traceback (most recent call last): File"raising_more_exceptions.py", line 8, in raise B('second') __main__.B: second |
但如果
1 | second |
问题
更新0
这个问题专门针对python 3,因为它的异常处理与python 2非常不同。
回答问题3,您可以使用:
1 | raise B('second') from None |
这将删除异常
1 2 3 4 | Traceback (most recent call last): File"raising_more_exceptions.py", line 8, in raise B('second') __main__.B: second |
"引发"异常在上一个异常处理程序中作为C."上下文"提供。python使用这些信息来呈现更有用的回溯。在python 2.x下,原来的异常会丢失,这只适用于python 3。
通常,在保持原始异常可访问的同时,您可以使用它来抛出一个一致的异常(尽管从异常处理程序自动发生非常酷,但我不知道!):
1 2 3 4 | try: do_something_involving_http() except (URLError, socket.timeout) as ex: raise MyError('Network error') from ex |
更多信息(以及您可以做的其他一些非常有用的事情):http://docs.python.org/3.3/library/exceptions.html
pythons异常处理一次只能处理一个异常。但是,异常对象和其他对象一样受相同的变量规则和垃圾收集的约束。因此,如果将异常对象保存在某个变量中,即使引发了另一个异常,也可以在以后处理它。
在您的例子中,当在"finally"语句中引发异常时,python 3将在第二个异常之前打印出第一个异常的回溯,这样更有用。
更常见的情况是,您希望在显式异常处理期间引发异常。然后您可以在下一个异常中"保存"该异常。只需将其作为参数传入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> class A(Exception): ... pass ... >>> class B(Exception): ... pass ... >>> try: ... try: ... raise A('first') ... except A as e: ... raise B('second', e) ... except Exception as c: ... print(c.args[1]) ... first |
如您所见,您现在可以访问原始异常。
我相信回答你问题的所有要素都已经在现有答案中了。让我结合并详细阐述。
让我重复您的问题代码,以提供行号参考:
1 2 3 4 5 6 7 8 9 10 | 1 class A(Exception): pass 2 class B(Exception): pass 3 4 try: 5 try: 6 raise A('first') 7 finally: 8 raise B('second') 9 except X as c: 10 print(c) |
所以要回答你的问题:
您的第一个异常
希望我对1的解释现在已经清楚了。不过,您可以捕获内部/下部/第一个异常。要合并Lennart的回答,稍微修改一下,下面介绍如何同时捕捉这两个问题:
1 2 3 4 5 6 7 8 9 | class A(Exception): pass class B(Exception): pass try: try: raise A('first') except A as e: raise B('second', e) except Exception as c: print(c) |
输出是:
1 | ('second', A('first',)) |
在Lennart的例子中,这个问题的解决方案是行
作为一种直觉一般的感觉,什么时候抓住例外,什么时候忽视它们,什么时候再提出,也许这个问题和亚历克斯·马泰利的回答有帮助。