一、定义
定义:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)
说人话:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)
>>>def addx(x):
>>> def adder(y): return x + y
>>> return adder
>>> c = addx(8)
>>> type(c)
>>> c.__name__
'adder'
>>> c(10)
结合这段简单的代码和定义来说明闭包:
如果在一个内部函数里:adder(y)就是这个内部函数,
对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域addx里面,但不在全局作用域里,
则这个内部函数adder就是一个闭包。
再稍微讲究一点的解释是,闭包=函数块+定义函数时的环境,adder就是函数块,x就是环境,当然这个环境可以有很多,不止一个简单的x。
二、使用闭包注意事项
1.闭包中是不能修改外部作用域的局部变量的
def f1():
m=1
def f2():
m=0
print(m)
print(m)
f2()
print(m)
f1()
#1
#0
#1
#[Finished in 0.1s]
2.使用闭包时一段经典的错误代码
ef foo():
a=1
def add():
nonlocal a #这句注释掉就会出错
a = a+1
return a
return add()
c=foo()
print(c)
#2
这段程序的本意是要通过在每次调用闭包函数时都对变量a进行递增的操作,但在实际使用时:因为在执行代码 c = foo()时,python会导入全部的闭包函数体add()来分析其的局部变量,python规则指定所有在赋值语句左面的变量都是局部变量,则在闭包add()中,变量a在赋值符号"="的左面,被python认为是add()中的局部变量。再接下来执行print (c)时,程序运行至a = a + 1时,因为先前已经把a归为add()中的局部变量,所以python会在add()中去找在赋值语句右面的a的值,结果找不到,就会报错。
解决的方法很简单:
使用语句nonloacal a就可以了,该语句显式的指定a不是闭包的局部变量。
参考博客:https://www.cnblogs.com/JohnABC/p/4076855.html