考虑:
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()
我希望看到Exception( "Test error" )
被提升,而只是#34;测试这个"打印出来。当然,目的是只召唤raiseMe()
一次,无论我们成功与否 - 但如果它引起异常,我本来想看到它!
为什么break会吞下我明确提出的异常?
答案 0 :(得分:32)
来自https://docs.python.org/2.7/reference/compound_stmts.html#finally:
如果finally存在,则指定'cleanup'处理程序。执行try子句,包括任何except和else子句。如果任何条款中发生异常且未处理,则暂时保存该异常。
执行finally子句。如果存在已保存的异常,则在finally子句的末尾重新引发。 如果finally子句引发另一个异常或执行return或break语句,则丢弃已保存的
异常
这也反映了PEP341之前try...finally
声明所期望的行为:
这是除了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< = 2.4的向后兼容性,必须以这种方式完成。
答案 1 :(得分:5)
答案 2 :(得分:1)
我认为经过反思,这是因为break实际上将StopIteration提升为for-loop的“break”。这实际上不是很直观,也没有特别详细记录(例如,1没有提及)。也许有人可以更好地确认/解释它?
答案 3 :(得分:0)
具有以下代码结构:
def func():
try:
driver.do("something")
except TimeoutException:
pass
finally:
result = driver.do("something else")
return result
通过pylint得到异常:
return statement in finally block may swallow exception (lost-exception)
解决方案是将 return 放在 finally 语句之外:
def func():
try:
driver.do("something")
except TimeoutException:
pass
finally:
result = driver.do("something else")
return result # <<