Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.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 finally block snowns异常中的Break语句_Python - Fatal编程技术网

Python finally block snowns异常中的Break语句

Python finally block snowns异常中的Break语句,python,Python,考虑: def raiseMe( text="Test error" ): raise Exception( text ) def break_in_finally_test(): for i in range(5): if i==2: try: raiseMe() except: raise else:

考虑:

def raiseMe( text="Test error" ):
    raise Exception( text )

def break_in_finally_test():
    for i in range(5):
        if i==2:
            try:
                raiseMe()
            except:
                raise
            else:
                print "succeeded!"
            finally:
                print "testing this!"
                break

if __name__=='__main__':
    break_in_finally_test()
我希望看到出现异常(“测试错误”),但只打印“测试此”。当然,我们的意图是只调用一次
raiseMe()
,不管我们成功与否——但如果它引发了一个异常,我会希望看到它

为什么break会吞下我显式提出的异常?

经过思考,我认为这是因为break实际上提出了一个StopIteration来“中断”for循环。这确实不是很直观,也没有很好的文档记录(例如,没有提到)。也许有人能更好地证实/解释一下吗

从文档中:

无论是否发生异常,finally子句总是在离开try语句之前执行

您的异常永远不会引发,因为您在try语句得到完全计算之前中断。

来自:

如果finally存在,它将指定一个“cleanup”处理程序。try子句被执行,包括任何except和else子句。如果
任何子句中发生异常且未处理,则会临时保存该异常
执行finally子句。如果存在保存的异常,则在finally子句末尾重新引发该异常如果finally子句引发另一个异常或执行return或break语句,则保存的异常将被丢弃

这也反映了以下情况之前的
try…finally
语句所期望的行为:

这就是try except finally块与PEP341前版本的相似之处:

try:
    try:
        raiseMe()
    except:
        raise
finally:
    #here is where cleanup is supposed to happen before raising error
    break
    #after finally code: raise error
由于在
finally
块中从未发生错误的提升,因此它实际上从未被提升


要保持与Python的向后兼容性,请使用以下代码结构:

def func():
    try: 
        driver.do("something")
    except TimeoutException:
        pass
    finally:
        result = driver.do("something else")
        return result
已通过pylint获取异常:

finally块中的return语句可能会吞没异常(丢失的异常)

解决方案是将return放在finally语句之外:

def func():
    try: 
        driver.do("something")
    except TimeoutException:
        pass
    finally:
        result = driver.do("something else")
    return result # << 
def func():
尝试:
司机:做(“某事”)
除TimeoutException外:
通过
最后:
结果=驱动程序。执行(“其他操作”)

返回结果#我不知道为什么会发生这种情况(我觉得有点奇怪),但是你可以在
else
内部中断,因为在出现异常的情况下,它无论如何都会退出循环。我可以理解
return
in finally是如何工作的,但是使用
break
这很奇怪。您的示例没有涵盖这一点,但该方法甚至会在循环后继续执行!这是真的吗,还是仅仅是猜测?如果是这样,那么我不应该捕获由循环中断引起的StopIteration异常吗?在for循环中手动提升StopIteration也没有同样的效果。@tobias_k这是一个-可能是错误的-猜测。文档确实解释了这一点-请参阅已接受的答案。好的,所以它是有文档记录的。但我不得不说,我仍然觉得这种行为非常令人惊讶(与大多数python行为不同,这种行为通常非常直观)。我的感觉是,特朗普应该回归或打破……蒂莫我同意。我想知道这是否不是以这种方式实现的,因为他们不必覆盖这种特定类型的块的break行为。