如何在不停止/退出程序的情况下捕获和打印完整的异常回溯? [英] How to catch and print the full exception traceback without halting/exiting the program?
问题描述
我想在不退出的情况下捕获和记录异常,例如
I want to catch and log exceptions without exiting, e.g.,
try:
do_stuff()
except Exception as err:
print(Exception, err)
# I want to print the entire traceback here,
# not just the exception name and details
我想打印与在没有 try..except 拦截异常的情况下引发异常时打印的完全相同的输出,并且我不希望它退出我的程序.我该怎么做?
I want to print the exact same output that is printed when the exception is raised without the try..except intercepting the exception, and I do not want it to exit my program. How do I do this?
推荐答案
其他一些答案已经指出 traceback 模块.
Some other answer have already pointed out the traceback module.
请注意,使用 print_exc
,在某些极端情况下,您将无法获得预期的结果.在 Python 2.x 中:
Please notice that with print_exc
, in some corner cases, you will not obtain what you would expect. In Python 2.x:
import traceback
try:
raise TypeError("Oups!")
except Exception, err:
try:
raise TypeError("Again !?!")
except:
pass
traceback.print_exc()
...将显示 last 异常的回溯:
...will display the traceback of the last exception:
Traceback (most recent call last):
File "e.py", line 7, in <module>
raise TypeError("Again !?!")
TypeError: Again !?!
如果您确实需要访问原始traceback,一种解决方案是缓存从exc_info
在局部变量中并使用 print_exception
:
If you really need to access the original traceback one solution is to cache the exception infos as returned from exc_info
in a local variable and display it using print_exception
:
import traceback
import sys
try:
raise TypeError("Oups!")
except Exception, err:
try:
exc_info = sys.exc_info()
# do you usefull stuff here
# (potentially raising an exception)
try:
raise TypeError("Again !?!")
except:
pass
# end of useful stuff
finally:
# Display the *original* exception
traceback.print_exception(*exc_info)
del exc_info
制作:
Traceback (most recent call last):
File "t.py", line 6, in <module>
raise TypeError("Oups!")
TypeError: Oups!
尽管如此,但很少有陷阱:
Few pitfalls with this though:
来自
sys_info
的文档:
将回溯返回值分配给处理异常的函数中的局部变量会导致循环引用.这将防止同一函数中的局部变量或回溯引用的任何内容被垃圾收集.[...] 如果确实需要回溯,请确保在使用后将其删除(最好使用 try ... finally 语句完成)
Assigning the traceback return value to a local variable in a function that is handling an exception will cause a circular reference. This will prevent anything referenced by a local variable in the same function or by the traceback from being garbage collected. [...] If you do need the traceback, make sure to delete it after use (best done with a try ... finally statement)
但是,来自同一个文档:
but, from the same doc:
从 Python 2.2 开始,此类循环会在启用垃圾收集且无法访问时自动回收,但避免创建循环仍然更有效.
Beginning with Python 2.2, such cycles are automatically reclaimed when garbage collection is enabled and they become unreachable, but it remains more efficient to avoid creating cycles.
另一方面,通过允许您访问与异常相关的回溯,Python 3 产生了一个不那么令人惊讶的结果:
On the other hand, by allowing you to access the traceback associated with an exception, Python 3 produce a less surprising result:
import traceback
try:
raise TypeError("Oups!")
except Exception as err:
try:
raise TypeError("Again !?!")
except:
pass
traceback.print_tb(err.__traceback__)
... 将显示:
File "e3.py", line 4, in <module>
raise TypeError("Oups!")
这篇关于如何在不停止/退出程序的情况下捕获和打印完整的异常回溯?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!