1、什么是闭包?
2、闭包有什么用?
3、闭包的应用场景?
今天带着以上三个问题来学习闭包。
1.嵌套函数
在学习闭包之前,我们先来看看嵌套函数。
# 普通函数:嵌套函数
def normal():
msg = '这是一个普通嵌套函数'
def print_msg():
nonlocal msg msg += "hhhh"
print(msg)
print_msg()
2.闭包
先来上一个闭包的例子,咱们再来分析哦:
# 闭包函数例子1
def closure():
msg = '这是一个闭包函数,这个msg是外部自由变量'
def inner():
print(msg)
·return inner
以上就是一个闭包函数哦,接着我们来分析一下组成闭包函数的条件。
2.1 闭包的条件:
(1)我们必须有一个嵌套函数(函数在函数内部)。
(2)嵌套函数必须引用在封闭函数(外部自由变量)中定义的值。
(3)封闭函数必须返回嵌套函数。
看到这里可以比对一下嵌套函数哦,1中的嵌套函数也是引用了封闭函数中定义的变量,但是返回这里没有返回嵌套函数,所以不能是一个闭包。1
2.1 闭包的定义:
接下来咱们再来分析下闭包的定义到底是什么?
首先,看下维基百科上的解释是:
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
其实,看完这个,感觉有点绕。
用自己的理解,自己的语言来说闭包,我觉得闭包是什么呢?
闭包本质上就是一个函数,有两部分组成:函数和自由变量。
闭包使得这些变量的值始终保存在内存中。
下图中的add2就是一个闭包,它由函数wrapper和变量x组成!
2.2 闭包的自由变量:
为什么说闭包的自由变量始终在内存中呢?可以理解为闭包中的自由变量存储在cell 对象的cell_contents !!!
所有函数都有一个 __closure__属性,如果这个函数是一个闭包的话,那么它返回的是一个由 cell 对象 组成的元组对象。cell 对象的cell_contents 属性就是闭包中的自由变量。
3.为什么要用闭包呢?
结合以上的例子,个人理解:闭包避免了全局变量的使用。
(1)、 全局变量容易被篡改。
(2) 、 闭包中的自由变量就相当于对象中的一个属性。 其实在对象函数较少时,为了简便,就可以直接使用闭包来实现,而不用对象也可以。
4. 闭包的应用场景
(1) 装饰器