前提: python的函数是一等对象:即可以赋值给变量,可以添加到集合中,可以传参到函数中,也可以当做函数的返回值。
定义: 是一种延伸了作用域的函数,会保留定义函数时存在的外层非全局变量的绑定。
通俗解释: 即在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包。在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
def outer(a):
def inner():
nonlocal(a) # a为嵌套作用域内变量,可以直接访问,但无法修改,若修改需加nonlocal关键字或者变成可变对象,否则报错
a+=1
return a
return inner
tmp=outer(1)
print(tmp())
print(tmp())
print(tmp())
执行后,相继输出2,3,4
闭包的好处:
- 共享变量时,既可以使对象持久,同时也避免了使用不安全的全局变量;
- 允许将函数与某些数据联系起来,类似于简化版面向对象编程,是实现面向对象的方式之一;
- 相同代码每次生成的闭包,延伸的作用域都彼此独立;
def outer(a): def inner(): nonlocal(a) # a为嵌套作用域内变量,可以直接访问,但无法修改,若修改需加nonlocal关键字或者变成可变对象,否则报错 a += 1 return a return inner tmp1 = outer(1) tmp2 = outer(1) print(tmp1()) print(tmp1()) print(tmp2()) print(tmp2()) 执行后,相继输出2,3,2,3
- 可以替代简单的类,并且内存开销低,类的生命周期远远大于闭包;
- 可以用来实现装饰器,这个在后续文章中细讲;
注意: 函数也是对象,函数名后边跟()相当于对函数对象的调用,不跟()则只是存了函数所在位置的引用;