如何在不停止/退出程序的情况下捕获并打印完整的异常回溯? [英] 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, 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?
推荐答案
其他一些答案已经指出了跟踪模块.
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
,然后使用
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!
与此相伴的陷阱很少:
-
来自
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屋!