对于不可变变量b, 在f1()中先赋值,后引用,这时候b是函数f1()内声明的局部变量,跟全局变量b没有关系。
b = 6
def f1(a):
"""
变量b, “先赋值,后引用” ,不会报错
"""
print(a)
b = 1
print(b)
对于不可变变量b,直接在f2()中引用会编译不通过,解释器会认为变量b是局部变量,在f2()中没有找到变量b的声明,就会编译出错。
b = 6
def f2(a):
"""
变量b, “先引用,后赋值”,则会报错
原因:Python不要求声明变量,但是假定在函数定义体中赋值的变量是局部变量
可以通过global关键字告诉解释器这个是全局变量
"""
print(a)
print(b)
b = 1
嵌套函数中,内部函数需要引用(并修改)外部函数中的局部变量,这个时候直接引用变量c,python解释器在内函数的作用域中找不到变量c的声明,就会报错,需要通过nonlocal关键字来声明变量c为自由变量。
def f3():
c = 2
def f4():
nonlocal c
c += 2
print(c)
return f4
闭包:引入了自由变量的函数就是闭包。这个被引入的自由变量和这个函数一同存在,即使这个变量已经离开了创造它的环境也不例外。(闭包中的自由变量,有点类似类中的属性)
一般对函数的理解:函数再被调用的时候,会在栈上创建其执行环境,初始化其中定义的变量和外部传入的参数,以便函数执行下一步的操作。当函数执行完成,并返回函数结果后,函数之前栈内存便会被销毁,函数中的临时变量以及存储的中间计算结果都不会保留。每次调用执行函数,都会重新初始化函数的执行环境。
闭包是另一种情况,外部函数发现,自己的临时变量,会在将来的内部函数中用到,外部函数在自己结束并返回内部函数的同时,会把外部函数的临时变量送给内函数绑定在一起,所以,外部函数结束了,但是调用内函数的时候仍可以使用外部函数的临时变量(或者说是内部函数的自由变量)。