直接上代码:

def fun3():
    try:
        x=[1,2,3]
        raise
        return x.append(6)
    except Exception:
        x.append(4)
        return x
    finally:
        x.append(5)
        print("fun3 finally")
print(fun3())
结果:
fun3 finally
[1, 2, 3, 4, 5]

代码中我们根据一个可变变量x来跟踪代码的执行顺序。

如果没有return,我们很容易判断,是先执行try代码块,然后执行except代码块(如果有异常),最后执行finally代码块
加入return后执行顺序便没有改变,执行return语句的结果不会立即返回,待finally执行完毕后再返回(执行第一个遇到的可执行的return,无论return是在try、except还是finally)

return语句后面的代码为什么会影响被保存的结果呢?那是因为python语言中对于变量的引用有两种形式:

值传递:

如数值,字符串,布尔类型,就是值传递,值传递在传参时实际上是将自身复制一份,函数内部使用的实际上是传入变量的副本,所以在函数体内部修改后,函数外部变量的值不会改变

引用传递:

如list,对象等,就是引用传递,引用传递在传参时实际上是将变量的引用复制一份,函数内部使用的是变量的引用,在函数内部改变参数值,通过引用改变了原来的值,所以函数内部改变参数的值时,函数外部的值也跟着改变。

函数内部和外部分别代表变量作用域的低一层和高一层,作用域的最高层即为全局变量

在这里可以理解为return语句前比语句后的作用域要低一层。如果是值传递,return后面的执行的代码不会改变return返回的结果,如果时引用传递return后面的代码就有可能会改变将要返回的结果。