我在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中实现这个目标吗?
答案 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)处理这个问题,以防你想要传递原因树而不是简单的原因链。也许它可以帮助你。