【问题标题】:In Python, how to tell if being called by exception handling code?在 Python 中,如何判断是否被异常处理代码调用?
【发布时间】:2009-07-27 08:40:55
【问题描述】:

我想在 Python (2.6) 中编写一个函数,该函数可以确定它是否被堆栈上某处的异常处理代码调用。

这是专门用于日志记录的。在 python 的logging 模块中,调用者必须明确指定应记录异常信息(通过调用logger.exception() 或使用exc_info 关键字)。我希望我的记录器自动执行此操作,具体取决于是否从异常处理代码中调用它。

我认为检查 sys.exc_info() 可能是答案,但它也会从已处理的异常中返回异常信息。 (来自docs:“此函数返回一个包含三个值的元组,这些值提供有关当前正在处理的异常的信息……如果当前堆栈帧未处理异常,则该信息取自调用堆栈帧,或其调用者,依此类推,直到找到正在处理异常的堆栈帧。这里,“处理异常”定义为“正在执行或已执行除了子句。'")

另外,由于我希望这对调用者透明,我不想在 except 子句中使用 exc_clear() 或其他任何内容。

这样做的正确方法是什么?

【问题讨论】:

  • 调用上下文怎么可能不明确?您定义了一个要从异常中调用的函数。它总是从异常中调用。有什么问题?请说明为什么设计为从异常中调用的函数不会从异常中调用。
  • 我没有将其定义为要从异常中调用的函数。它是一个可以从异常调用或从非异常调用的函数。我想确定是哪种情况。
  • Ummm... 定义你的函数有什么问题,所以它必须从异常中调用?是什么阻止您更改函数定义以简化此操作?
  • 或将您的函数“分叉”为两部分:一个仅从异常处理程序调用,另一个在所有其他情况下调用(如果我理解正确的话)。

标签: python exception


【解决方案1】:

如果您在异常处理程序中使用sys.exc_clear 清除异常,那么sys.exc_info 应该适合您。例如:如果您运行以下脚本:

import sys

try:
    1 / 0
except:
    print sys.exc_info()
    sys.exc_clear()
print sys.exc_info()

你应该看到这个输出:

(, ZeroDivisionError('整数除或模零',), ) (无,无,无)

更新:我认为没有一种简单(“透明”)的方式可以回答“异常处理程序是否正在运行?”这个问题。不费吹灰之力,在我看来,仅仅为了日志记录不值得麻烦。回答“是否引发了异常(在此线程中)?”这个问题当然很容易,即使是在每个堆栈帧的基础上(请参阅帧对象的文档)。

【讨论】:

  • 感谢 Vinay,但我正在寻找一种对调用者透明的方法;也就是说,在 except 子句中不需要任何特殊内容。我将把问题编辑得更具体。
【解决方案2】:

就像 Python 中的一切一样,异常是一个对象。因此,您可以保留对最后处理的异常的(弱!)引用,然后使用sys.exc_info()。 注意:在多线程代码的情况下,您可能会遇到这种方法的问题。并且可能还有其他极端情况。

但是,explicit is better than implicit;您真的确定以与正常日志相同的方式处理异常日志是添加到系统中的一项好功能吗?
依我拙见,不是。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 2016-10-12
    • 2018-12-17
    • 2012-04-22
    • 2014-01-01
    • 1970-01-01
    • 2013-02-19
    相关资源
    最近更新 更多