sys.exc_info()如何工作?

时间:2013-06-07 00:39:37

标签: python exception python-2.7

sys.exc_info()的行为在python docs以及SOSO中描述为:

  • 在except块或由except块调用的方法中,描述异常的三元组
  • 其他地方,无价值的三倍

那为什么这个鼻子会失败?

def test_lang_stack(self):
    try:
        self.assertEquals((None,None,None), sys.exc_info()) # no exception
        a = 5 / 0
    except:
        self.assertNotEquals((None,None,None), sys.exc_info())  # got exception
    else:
        self.fail('should not get here')
    #finally:
    #    self.assertEquals((None,None,None), sys.exc_info()) # already handled, right?
    self.assertEquals((None,None,None), sys.exc_info())  # already handled, right?

最后一行失败了。如果你取消注释finally块,它就会失败。

我确实看到如果我将所有这些放在一个方法中并从另一个方法调用,那么调用方法不会看到异常。即使在处理了异常之后,exc_info值仍然设置为抛出异常的方法的结尾。

我在OSX上使用python2.7。

2 个答案:

答案 0 :(得分:2)

在assertEquals()和assertNotEquals()中,你需要调用:

sys.exc_clear()

这将清除下一个错误。

答案 1 :(得分:2)

在回答你的问题之前,我必须解释一下sys.exc_info()确定程序中最新/最近的异常: -

  

您的程序基本上是一系列函数调用,具有调用者   函数调用调用。这样就形成了一个调用栈/执行栈,   为每个函数推送一个条目,被调用。这个条目   在python中被称为堆栈帧。因此,当你的程序,   调用sys.exc_info(),它使用以下序列   确定最新的例外。它从当前的堆栈帧开始,   这是您调用sys.exc_info()的函数。如果   当前堆栈帧没有处理/没有处理异常,   信息来自调用堆栈帧或其调用者,   等等,直到找到处理/处理过的堆栈帧   例外。这里,“处理异常”被定义为“执行或   执行了一个except子句。“对于任何堆栈帧,只有   可以访问有关最近处理的异常的信息。

现在,来看你的代码,

def test_lang_stack(self):
    try:
        self.assertEquals((None,None,None), sys.exc_info()) # no exception
        a = 5 / 0
    except:
        self.assertNotEquals((None,None,None), sys.exc_info())  # got exception
    else:
        self.fail('should not get here')
    #finally:
    #    self.assertEquals((None,None,None), sys.exc_info()) # already handled, right?
    self.assertEquals((None,None,None), sys.exc_info())  # already handled, right?

根据上面解释的过程,sys.exc_info()将始终在函数中找到最近处理的异常。所以,除非你明确地致电sys.exec_clear(),否则它永远不会是Nones的元组。

我希望,它可以帮助你。