闭包概念:
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)
闭包=函数块+定义函数时的环境
内层函数就是函数块,被内层调用的外层变量就是环境,当然这个环境可以有很多
def 外层函数():
def 内层函数():
return 计算值
return 内层函数
外层的参数(形参与实参)都可被内层函数调用
函数名:函数对象
函数名():函数调用
注:返回函数不要引用任何循环变量,或者后续会发生变化的变量
廖雪峰网站的例子:
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f())
return fs
f1, f2, f3 = count()
内层函数返回值使用了循环变量,然后到了外层函数时调用内层函数并添加到列表,最后返回这个列表
原本预期 这个列表的值是 1,4,9 但是这个列表值是 9,9,9
原来内层函数返回值时 不会立刻执行 当内层函数全返回时 i已经变成了3
如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改
已绑定到函数参数的值不变
例
def s():
def c(i):
def g():
return i*i
return g
a=[]
for i in range(1,4):
a.append(c(i))
return a
a=s()
for i in a:
print(i())
调用内部闭包,将函数对象放置到列表中并返回
a=s()
for i in a:
print(i())
调用内部闭包,将函数对象放置到列表中并返回
闭包的特性就是:内嵌函数会保存它引用的外围函数的变量值
def time():
s=0
def add():
nonloacal s
s=s+1
return s
return add
a=time()
a()
a()
print(a()) 打印值为3
内部函数无法修改外层函数的局部变量 nonloacal声明为外层变量(非全局变量)即可