【问题标题】:Handling a Python exception that occurs within an except clause处理出现在 except 子句中的 Python 异常
【发布时间】:2010-01-21 02:14:32
【问题描述】:

我在 Python except 子句中有一些代码用于进行一些日志记录,但日志记录代码本身可能会导致异常。就我而言,我想忽略可能发生的任何第二个异常,并引发原始异常。这是一个非常简化的示例:

try:
    a = this_variable_doesnt_exist
except:
    try:
        1/0
    except:
        pass
    raise

运行上面的代码,希望得到:

NameError: name 'this_variable_doesnt_exist' is not defined

但是,在 Python 2.x 中,我得到:

ZeroDivisionError: integer division or modulo by zero

我发现在 Python 3.x 中,它可以满足我的需求。

我在 Python 2.x 文档中找不到太多关于此的评论(除非我错过了)。我可以在 2.x 中实现这一点吗?

【问题讨论】:

    标签: python exception


    【解决方案1】:

    我相信您看到的是exception chaining 的结果,即change in Python 3

    来自 PEP 的动机部分:

    在处理一个异常(异常A)期间,可能会发生另一个异常(异常B)。在今天的 Python(2.4 版)中,如果发生这种情况,异常 B 会向外传播,异常 A 会丢失。为了调试问题,了解这两个异常很有用。 __context__ 属性会自动保留此信息。

    然后,PEP 继续详细描述了新的异常链(在 Py3k 中实现)——这是一本有趣的读物。我今天学到了一些新东西。

    【讨论】:

    • 应该如何明确处理次要异常?请在您的答案中包含此内容
    【解决方案2】:

    有抽象:

    def log_it():
        try:
            1 / 0
        except:
            pass
    
    try:
        this = that
    except:
        log_it()
        raise
    

    在 Python 2.5 中做你想做的事

    另一种方法是将异常存储在一个变量中,然后显式地重新引发它:

    try:
        this = that
    except NameError, e: # or NameError as e for Python 2.6
        try:
            1 / 0
        except:
            pass
        raise e
    

    请注意,您可能不应该只使用简单的 except 来捕获可能发生的所有事情 - 通常最好捕获您期望发生的特定异常,以防剧烈和致命的异常(例如内存不足) ) 发生。

    【讨论】:

      【解决方案3】:

      在我的CausedException class 中,我会为 Python 2.x(以及 Python 3,以防您想要传递原因树而不是简单的原因链)进行处理。也许它可以帮助你。

      【讨论】:

      • 虽然理论上这可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多