什么是闭包
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。 上面提到了两个关键的地方: 自由变量 和 函数, 这两个关键稍后再说。还是得在赘述下“闭包”的意思,望文知意,可以形象的把它理解为一个封闭的包裹,这个包裹就是一个函数,当然还有函数内部对应的逻辑,包裹里面的东西就是自由变量,自由变量可以在随着包裹到处游荡。当然还得有个前提,这个包裹是被创建出来的。
再通过Python的语言介绍一下,一个闭包就是你调用了一个函数A,这个函数A返回了一个函数B给你。这个返回的函数B就叫做闭包。你在调用函数A的时候传递的参数就是自由变量。 举个栗子:
1 |
|
调用fa的时候就产生了一个闭包fb,并且该闭包持有自由变量num,因此这意味着,当函数func的生命周期结束之后,name这个变量依旧存在,因为他被闭包引用了,所以不会回收。
举例闭包的使用场景
1 |
|
nonlocal语句
在python的函数内,可以直接引用外部变量,但是不能改写外部变量,因此如果在闭包中直接改写父函数的变量,就会发生错误,例如:
1 |
|
在python2中可以在函数内使用global语句,但是全局变量在任何语言中都不被提倡,因为它很难控制,python3中引入了nonlocal语句来解决这个问题:
1 |
|
nonlocal与global的区别在与nonlocal语句回去搜寻本地变量与全局变量之间的变量,其会优先寻找层级关系与闭包作用域最近的外部变量。
装饰器模式
装饰器是函数闭包的一种应用。装饰器函数用来装饰一般函数(给一个函数增加额外的功能),然后返回新的函数对象给函数本身。具体还是看代码演示:
1 |
|
运行结果:
1 |
|
闭包的作用
闭包的最大特点是可以将父函数的变量与内部函数绑定,并返回绑定变量后的函数(也即闭包),此时即便生成闭包的环境(父函数)已经释放,闭包仍然存在,这个过程很像类(父函数)生成实例(闭包),不同的是父函数只在调用时执行,执行完毕后其环境就会释放,而类则在文件执行时创建,一般程序执行完毕后作用域才释放,因此对一些需要重用的功能且不足以定义为类的行为,使用闭包会比使用类占用更少的资源,且更轻巧灵活
闭包可以避免全局变量的使用。
对闭包的理解还是需要多多实践,多多体会。
本文参考: http://www.mylanbitou.top/blog/detail/3/#Coon