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

时间:2010-01-21 02:14:32

标签: python exception

我在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中实现这个目标吗?

3 个答案:

答案 0 :(得分:22)

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

来自PEP的 Motivation 部分:

  

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

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

答案 1 :(得分:17)

抽象:

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来捕获可能出现的所有内容 - 通常最好捕获您期望发生的特定异常,以防出现严重且致命的异常(如外出发生。)

答案 2 :(得分:0)

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