97

下面有一段有趣的代码:

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

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

func1()
func2()

请有人解释一下,什么结果将返回这两个函数并解释原因,即描述执行顺序

4

4 回答 4

171

来自 Python文档

finally 子句总是在离开 try 语句之前执行,无论是否发生异常。当 try 子句中发生异常并且没有被 except 子句处理(或者它已经发生在 except 或 else 子句中)时,它会在 finally 子句执行后重新引发。当 try 语句的任何其他子句通过 break、continue 或 return 语句离开时,finally 子句也会“在退出时”执行。一个更复杂的示例(从 Python 2.5 开始,在同一 try 语句中具有 except 和 finally 子句):

因此,一旦使用return留下 try/except 块,这会将返回值设置为给定 - finally 块将始终执行,并且应该用于释放资源等,同时使用另一个 return - 覆盖原始的。

在您的特定情况下,func1()return2func2()return 3,因为这些是 finally 块中返回的值。

于 2013-11-06T06:45:27.183 回答
50

它总是会去finally块,所以它会忽略andreturn中的。如果您在and上方有 a ,它将返回该值。tryexceptreturntryexcept

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
于 2013-11-06T06:49:37.020 回答
16

事先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。

于 2013-11-06T06:48:56.380 回答
3

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

finally块最终执行,无论或异常。

您可以使用调试器查看执行顺序。例如,查看截屏视频

于 2013-11-06T06:47:08.253 回答