下面有一些有趣的代码:
def func1():
try:
return 1
finally:
return 2
def func2():
try:
raise ValueError()
except:
return 1
finally:
return 3
func1()
func2()
可以请某人解释,结果将返回这两个函数并解释原因,即描述执行的顺序
答案 0 :(得分:91)
来自Python documentation
在离开try语句之前总是执行finally子句,无论是否发生了异常。当try子句中发生异常且尚未由except子句处理(或者它发生在except或else子句中)时,在finally子句执行后重新引发它。当try语句的任何其他子句通过break,continue或return语句时,finally子句也会在“出路”时执行。一个更复杂的例子(在同一个try语句中使用except和finally子句的工作方式与Python 2.5一样):
所以一旦使用返回继续使用try / except块,这会将返回值设置为给定 - 最后块将始终执行,并且应该用于释放在那里使用另一个返回的资源等 - 覆盖原始的。
在您的特定情况下,func1()
返回2
并func2()
返回3
,因为这些是在finally块中返回的值。
答案 1 :(得分:27)
它将始终转到finally
块,因此会忽略return
和try
中的except
。如果您return
和try
之上的except
,则会返回该值。
def func1():
try:
return 1 # ignoring the return
finally:
return 2 # returns this return
def func2():
try:
raise ValueError()
except:
# is going to this exception block, but ignores the return because it needs to go to the finally
return 1
finally:
return 3
def func3():
return 0 # finds a return here, before the try except and finally block, so it will use this return
try:
raise ValueError()
except:
return 1
finally:
return 3
func1() # returns 2
func2() # returns 3
func3() # returns 0
答案 2 :(得分:7)
预先放置print
语句真的很有帮助:
def func1():
try:
print 'try statement in func1. after this return 1'
return 1
finally:
print 'after the try statement in func1, return 2'
return 2
def func2():
try:
print 'raise a value error'
raise ValueError()
except:
print 'an error has been raised! return 1!'
return 1
finally:
print 'okay after all that let\'s return 3'
return 3
print func1()
print func2()
返回:
try statement in func1. after this return 1
after the try statement in func1, return 2
2
raise a value error
an error has been raised! return 1!
okay after all that let's return 3
3
你会发现python总是返回要返回的最后一件事,不管代码是否在两个函数中“到达”return 1
。
finally
块始终运行,因此函数中返回的最后一件事是finally块中返回的内容。在func1
中,那是2.在func2
中,那是3。
答案 3 :(得分:1)