处理在except子句中发生的Python异常

Cra*_*een 18 python exception

我在Python except子句中有一些代码用于执行某些日志记录,但日志记录代码本身可能会导致异常.在我的情况下,我想忽略可能发生的任何第二个异常,并引发原始异常.这是一个非常简单的例子:

try:
    a = this_variable_doesnt_exist
except:
    try:
        1/0
    except:
        pass
    raise
Run Code Online (Sandbox Code Playgroud)

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

NameError: name 'this_variable_doesnt_exist' is not defined
Run Code Online (Sandbox Code Playgroud)

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

ZeroDivisionError: integer division or modulo by zero
Run Code Online (Sandbox Code Playgroud)

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

我在Python 2.x文档中找不到这方面的评论(除非我错过了).我可以在2.x中实现这一点吗?

Alo*_*hal 22

我相信你所看到的是异常链接的结果,这是Python 3变化.

从PEP 的Motivation部分:

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

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

  • 应该如何明确处理次要异常?请将此包含在您的答案中 (6认同)

Chr*_*utz 17

抽象:

def log_it():
    try:
        1 / 0
    except:
        pass

try:
    this = that
except:
    log_it()
    raise
Run Code Online (Sandbox Code Playgroud)

在Python 2.5中你想要的是什么

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

try:
    this = that
except NameError, e: # or NameError as e for Python 2.6
    try:
        1 / 0
    except:
        pass
    raise e
Run Code Online (Sandbox Code Playgroud)

请注意,您可能不应该只使用裸存except来捕获可能出现的所有内容 - 通常最好捕获您期望发生的特定异常,以防发生严重且致命的异常(如内存不足).