定义
Python闭包表现为:如果在一个内部函数里,对在外部作用域(非全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
相比普通函数,闭包不仅可以传递功能,还可以传递数据
def outer(a):
b = 1
def inner():
# 内部函数inner中用到了外部函数的变量
print(a+b)
#外部函数outer的返回值是内部函数的引用
return inner
demo = outer(2)
type(demo) # <type 'function'>
demo.__name__ # 'inner'
demo() # 3
一般情况下,一个函数结束的时候,会把自己的临时变量都释放还给内存,之后变量都不存在了。但是闭包是一个特别的情况。外部函数发现,自己的临时变量会在将来的内部函数中用到,自己在结束的时候,返回内函数的同时,会把外函数的临时变量送给内函数绑定在一起。所以外函数已经结束了,调用内函数的时候仍然能够使用外函数的临时变量。
创建一个Python闭包
Python闭包(closure)必须满足以下三点标准:
- 必须有一个内嵌函数
- 内嵌函数必须用到定义在外部函数内的局部变量
- 外部函数必须返回内嵌函数
注意事项
闭包中不能修改外部作用域的局部变量的,
def outer():
a = 1
def inner():
a = a + 1
return a
return inner
demo = outer()
print(demo()) # Error
在闭包inner()中,变量a在赋值符号"="的左面,会被python认为是inner()中的局部变量,再接下来执行printa()时,程序运行至a = a + 1时,因为先前已经把a归为inner()中的局部变量,所以python会在inner()中去找在赋值语句右面的a的值,结果找不到,就会报错。
如果你非要修改也是可以的,有两种方法:
def outer():
b = 1 # a和b都是闭包变量
c = [3] #这里对应修改闭包变量的方法2
def inner():
#内函数中想修改闭包变量
# 方法1 nonlocal关键字声明
nonlocal b
b += 1
# 方法2,把闭包变量修改成可变数据类型 比如列表
c[0] += 1
print(b)
print(c[0])
# 外函数的返回值是内函数的引用
return inner
demo = outer()
demo() # 2 4
- 在python3中,可以用nonlocal 关键字声明 一个变量, 表示这个变量不是局部变量空间的变量,需要向上一层变量空间找这个变量。
- 在python2中,没有nonlocal这个关键字,我们可以把闭包变量改成可变类型数据进行修改,比如列表。
闭包的作用(待补)
- 当闭包执行完后,仍然能够保持住当前的运行环境
- 闭包可以根据外部作用域的局部变量来得到不同的结果