定义
在一个函数内部再定义一个函数(内层函数),内层函数引用了外层函数作用域里的一些变量(非全局变量,外层函数没有参数也行),则这个内层函数以及用到的变量统称为闭包(Closure)。
条件
1、必须是一个嵌套函数。
2、内层函数使用了外层函数的变量。
3、外层函数的返回值是内层函数的函数名。
实例
基本格式
def outer(a): #外层函数
b=10 #外层函数变量a,b
def inner(c): #内层函数
print("a+b+c=",a+b+c) #引用外层函数变量
return inner #返回内层函数名称
assigned_func=outer(5) #实例化外层函数,可实例化多个外层函数,不同实例之间互不影响
assigned_func(3) #调用闭包函数
#输出结果为:a+b+c= 18
对于闭包,在外函数outer中,最后return inner,我们在调用外函数 assigned_func = outer() 的时候,outer返回了inner,inner是一个函数的引用,这个引用被存入了assigned_func中。所以接下来我们再进行assigned_func() 的时候,相当于运行了inner函数。
一个函数,如果函数名后紧跟一对括号,相当于现在我就要调用这个函数,如果不跟括号,相当于只是一个函数的名字,里面存了函数所在位置的引用。
注意:闭包函数的调用需要首先实例化。
由于闭包引用了外部函数的变量,则外部函数的变量没有及时释放,消耗内存。
内层函数修改外层函数变量数据
函数内部想要修改全局变量,使用global关键字。
a=10
def func():
a=1 #重新定义a
print(a)
def global_func():
global a #声明使用全局变量,a不重新定义
print(a)
func()
print("-"*20)
global_func()
'''
输出结果为
1
--------------------
10
'''
在闭包函数内部,想要修改外层函数的局部变量,需要使用nonlocal关键字。
def outer(a): #外层函数
b=10 #外层函数变量b
def inner(c): #内层函数
nonlocal b #未声明时,变量b未在函数inner中定义,运行会报错
b=b*2
print("a+b+c=",a+b+c) #引用外层函数变量
return inner #返回内层函数名称
assigned_func=outer(5) #实例化外层函数
assigned_func(3) #调用闭包函数
#输出结果为:a+b+c= 28
闭包中引用的自由变量只和具体的闭包有关联,闭包的每个实例引用的自由变量互不干扰。
一个闭包实例对其自由变量的修改会被传递到下一次该闭包实例的调用
def outer(a): #外层函数
b=10 #外层函数变量b
def inner(c): #内层函数
nonlocal b #未声明时,变量b未在函数inner中定义,运行会报错
b=b*2
print("a+b+c=",a+b+c) #引用外层函数变量
return inner #返回内层函数名称
assigned_func=outer(5) #实例化外层函数
assigned_func(3) #调用闭包函数
#输出结果为:a+b+c= 28
assigned_func(3)
#输出结果为:a+b+c= 48
assigned_func(3)
#输出结果为:a+b+c= 88
闭包提供了更好的封装性和模块化能力,有助于提高代码的可维护性和复用性,但可能会增加内存使用和调试的复杂性。