Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python sys.exc_info()是如何工作的?_Python_Exception_Python 2.7 - Fatal编程技术网

Python sys.exc_info()是如何工作的?

Python sys.exc_info()是如何工作的?,python,exception,python-2.7,Python,Exception,Python 2.7,sys.exc_info()的行为在和中描述为: 在except块或except块调用的方法中,描述异常的三元组 在其他地方,三重无价值 那么为什么鼻子测试失败呢 def test_lang_stack(self): try: self.assertEquals((None,None,None), sys.exc_info()) # no exception a = 5 / 0 except: self.assertNotEqu

sys.exc_info()的行为在和中描述为:

  • 在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。

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

sys.exc_clear()

这将清除下一个错误。

在回答您的问题之前,我必须解释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\u clear()
,否则它永远不会是非元组


我希望它可以帮助您。

我可以像这样手动清除错误,但关键是exc_info()调用应该区分我正在处理异常的上下文(在except:block中)和未处理异常的上下文(在其他任何地方)。我不想在整个项目中的每个try/except语句之后都显式地添加exc_clear()!我认为设计是只在异常块中使用sys.exc_info()。我同意@user634943的观点,如果在except块之外调用exc_info(),则最好有一种方法返回(None,None,None)。不幸的是,这并没有神奇地发生,目前我们确实需要手动调用exc_clear()或@cforbish,有没有办法询问python一段代码是否是except块中的代码?