《Python语言程序设计》 —3.5.4 闭包

举报
华章计算机 发表于 2019/11/18 21:14:41 2019/11/18
【摘要】 本节书摘来自华章计算机《Python语言程序设计》一书中第3章,第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),且每个闭包可多次调用。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。