2010-01-21 61 views
11

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

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中实现这个吗?

回答

15

随着抽象:

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来捕捉所有可能出现的情况 - 通常最好捕获您期望的特定例外情况如果发生严重和致命异常(例如内存不足),则会发生。

18

我相信你看到的是exception chaining,这是一个change in Python 3的结果。

从PEP的动机部分:

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

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

+0

如何明确处理次要异常?请在你的回答中加入这个 – 2017-04-03 23:13:41

0

在我的CausedException class中,我关注了Python 2.x(也适用于Python 3,以防您想传递原因树而不是简单原因链)。也许它可以帮助你。

+1

虽然这可能在理论上回答这个问题,[这将是可取的](http://meta.stackexchange.com/q/8259)在这里包括答案的基本部分,并提供链接以供参考。 – 2013-11-10 19:35:15

相关问题