《Python语言程序设计》 —3.5.4 闭包
3.5.4 闭包
在介绍nonlocal关键字时,我们已经看到Python语言的函数可以采用嵌套定义的方式,即在一个函数的函数体中定义另外一个函数。如果内层函数使用了外层函数中定义的局部变量,并且外层函数的返回值是内层函数的引用,就构成了闭包。
定义在外层函数中但由内层函数使用的变量称为自由变量。一般情况下,如果一个函数结束,那么该函数中定义的局部变量都会释放。然而,闭包是一种特殊情况,外层函数在结束时会发现其定义的局部变量将来会在内层函数中使用,此时外层函数就会把这些自由变量绑定到内层函数。因此,所谓闭包,实际上就是将内层函数的代码以及自由变量(由外层函数定义,但会由内层函数使用)打包在一起。
例如,对于代码清单3-31:
代码清单3-31 闭包示例
1 def outer(x): #定义函数outer
2 y=10 #定义局部变量y并赋为10
3 def inner(z): #在outer函数中定义嵌套函数inner
4 nonlocal x,y #nonlocal声明
5 return x+y+z #返回x+y+z的结果
6 return inner #返回嵌套函数inner的引用
7 f=outer(5) #将返回的inner函数赋给f
8 g=outer(50) #将返回的inner函数赋给g
9 print('f(20)的值为', f(20))
10 print('g(20)的值为', g(20))
11 print('f(30)的值为', f(30))
12 print('g(30)的值为', g(30))
程序执行完毕后,将在屏幕上输出如下结果:
f(20)的值为 35
g(20)的值为 80
f(30)的值为 45
g(30)的值为 90
提示 在代码清单3-31的第7行代码中,通过f=outer(5)将outer返回的inner函数的引用赋给了f,此时outer函数中的两个局部变量x(=5)和y(=10)也同时绑定到返回的inner函数,形成了一个闭包;在第9行调用f(20)时,会将20传给f所对应的inner函数的形参z,因此f(20)最后返回的计算结果为x+y+z=5+10+20=35;类似地,在第11行调用f(30)时,会将30传给f所对应的inner函数的形参z,因此f(30)最后返回的计算结果为x+y+z=5+10+30=45。
在第8行代码中,通过g=outer(50)将outer返回的inner函数的引用赋给了g,此时outer函数中的两个局部变量x(=50)和y(=10)也同时绑定到返回的inner函数,形成了另一个闭包;在第10行调用g(20)时,会将20传给g所对应的inner函数的形参z,因此g(20)最后返回的计算结果为x+y+z=50+10+20=80;同样,在第12行调用g(30)时,会将30传给g所对应的inner函数的形参z,因此g(30)最后返回的计算结果为x+y+z=50+10+30=90。
闭包的主要作用在于可以封存函数执行的上下文环境。例如,对于代码清单3-31,
就通过两次调用outer函数形成了两个闭包,这两个闭包具有相互独立的上下文环境(一个闭包中x=5,y=10;另一个闭包中x=50,y=10),且每个闭包可多次调用。
- 点赞
- 收藏
- 关注作者
评论(0)