如何在不停止/退出程序的情况下捕获和打印完整的异常回溯? [英] How to catch and print the full exception traceback without halting/exiting the program?

查看:16
本文介绍了如何在不停止/退出程序的情况下捕获和打印完整的异常回溯?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在不退出的情况下捕获和记录异常,例如

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:

将回溯返回值分配给处理异常的函数中的局部变量会导致循环引用.这将防止同一函数中的局部变量或回溯引用的任何内容被垃圾收集.[...] 如果确实需要回溯,请确保在使用后将其删除(最好使用 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屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆