python中闭包Closure函数作为返回值的方法示例


Posted in Python onDecember 17, 2017

前言

首先看看闭包的概念:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,闭包是由函数和与其相关的引用环境组合而成的实体。

一、函数作为返回值

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

>>> def lazy_sum(*args):
...  def sum():
...   ax = 0
...   for n in args:
...    ax = ax + n
...   return ax
...  return sum
... 
>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
<function lazy_sum.<locals>.sum at 0x1014ae730>
>>> f()
25

当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数:

>>> f1 = lazy_sum(1, 3, 5, 7)
>>> f2 = lazy_sum(1, 3, 5, 7)
>>> f1
<function lazy_sum.<locals>.sum at 0x1014ae8c8>
>>> f2
<function lazy_sum.<locals>.sum at 0x1014ae7b8>
>>> f1 == f2
False

二、闭包

在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

简单的说,这种内部函数可以使用外部函数变量的行为,就叫闭包

在这个例子中,我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。

注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。

返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

>>> def count():
...  fs = []
...  for i in range(1, 4):
...   def f():
...    return i * i
...   fs.append(f)
...  return fs
... 
>>> f1, f2, f3 = count()
>>> f1()
9
>>> f2()
9
>>> f3()
9

全部都是9!原因就在于返回的函数引用了循环变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。

如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

>>> def count():
...  def f(j):
...   def g():
...    return j * j
...   return g
...  fs = []
...  for i in range(1, 4):
...   fs.append(f(i))
...  return fs
... 
>>> f1, f2, f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python自定义scrapy中间模块避免重复采集的方法
Apr 07 Python
python使用正则表达式提取网页URL的方法
May 26 Python
python 根据正则表达式提取指定的内容实例详解
Dec 04 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
Nov 21 Python
python3编写ThinkPHP命令执行Getshell的方法
Feb 26 Python
Python PO设计模式的具体使用
Aug 16 Python
python根据文本生成词云图代码实例
Nov 15 Python
Python3监控疫情的完整代码
Feb 20 Python
在Django中预防CSRF攻击的操作
Mar 13 Python
matplotlib设置颜色、标记、线条,让你的图像更加丰富(推荐)
Sep 25 Python
python基于openpyxl生成excel文件
Dec 23 Python
Python中第三方库Faker的使用详解
Apr 02 Python
django模板语法学习之include示例详解
Dec 17 #Python
详解python string类型 bytes类型 bytearray类型
Dec 16 #Python
python使用os.listdir和os.walk获得文件的路径的方法
Dec 16 #Python
python读取与写入csv格式文件的示例代码
Dec 16 #Python
浅谈用VSCode写python的正确姿势
Dec 16 #Python
numpy中索引和切片详解
Dec 15 #Python
Python实现简单网页图片抓取完整代码实例
Dec 15 #Python
You might like
PHP 和 MySQL 基础教程(一)
2006/10/09 PHP
php 生成静态页面的办法与实现代码详细版
2010/02/15 PHP
javascript Select标记中options操作方法集合
2008/10/22 Javascript
去掉gridPanel表头全选框的小例子
2013/07/18 Javascript
JavaScript检测弹出窗口是否已经关闭的方法
2015/03/24 Javascript
JavaScript实现随机替换图片的方法
2015/04/16 Javascript
JS实现超精简响应鼠标显示二级菜单代码
2015/09/12 Javascript
基于jquery实现日历签到功能
2020/09/11 Javascript
简单实现js选项卡切换效果
2016/02/03 Javascript
jQuery的each循环用法简单示例
2016/06/12 Javascript
浅谈JQuery+ajax+jsonp 跨域访问
2016/06/25 Javascript
jQuery实现每隔几条元素增加1条线的方法
2016/06/27 Javascript
jQuery实现手机上输入后隐藏键盘功能
2017/01/04 Javascript
Bootstrap与Angularjs的模态框实例代码
2017/08/03 Javascript
[js高手之路]设计模式系列课程-发布者,订阅者重构购物车的实例
2017/08/29 Javascript
Vue实现调节窗口大小时触发事件动态调节更新组件尺寸的方法
2018/09/15 Javascript
微信小程序实现同一页面取值的方法分析
2019/04/30 Javascript
JavaScript Dom 绑定事件操作实例详解
2019/10/02 Javascript
小程序组件传值和引入sass的方法(使用vant Weapp组件库)
2020/11/24 Javascript
pycharm 使用心得(六)进行简单的数据库管理
2014/06/06 Python
基于python select.select模块通信的实例讲解
2017/09/21 Python
Python产生一个数值范围内的不重复的随机数的实现方法
2019/08/21 Python
wxPython多个窗口的基本结构
2019/11/19 Python
Python scrapy增量爬取实例及实现过程解析
2019/12/24 Python
python 项目目录结构设置
2020/02/14 Python
python中shell执行知识点
2020/05/06 Python
美国孕妇装品牌:Destination Maternity
2018/02/04 全球购物
法国最大电子商务平台:Cdiscount
2018/03/13 全球购物
端口镜像是怎么实现的
2014/03/25 面试题
电气工程及其自动化学生实习自我鉴定
2013/09/19 职场文书
工地门卫岗位职责
2013/12/30 职场文书
酒店值班经理的工作职责范本
2014/02/18 职场文书
多媒体专业自我鉴定
2014/02/28 职场文书
市场营销专业毕业生求职信
2014/07/21 职场文书
中学生爱国演讲稿
2014/09/05 职场文书
2014年底工作总结
2014/12/15 职场文书