Python尝试finally块返回

时间:2013-11-06 06:39:21

标签: python try-catch try-except try-finally

下面有一些有趣的代码:

def func1():
    try:
        return 1
    finally:
        return 2

def func2():
    try:
        raise ValueError()
    except:
        return 1
    finally:
        return 3

func1()
func2()

可以请某人解释,结果将返回这两个函数并解释原因,即描述执行的顺序

4 个答案:

答案 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()返回2func2()返回3,因为这些是在finally块中返回的值。

答案 1 :(得分:27)

它将始终转到finally块,因此会忽略returntry中的except。如果您returntry之上的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)

func1()返回2. func2()返回3.

无论是异常还是异常,都会执行

finally块。

您可以使用调试器查看执行顺序。例如,请参阅a screencast