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绘制MySQL数据图实现数据可视化
Mar 30 Python
用Python进行基础的函数式编程的教程
Mar 31 Python
使用rpclib进行Python网络编程时的注释问题
May 06 Python
Python中字典的基本知识初步介绍
May 21 Python
Python中list初始化方法示例
Sep 18 Python
Python 爬虫学习笔记之多线程爬虫
Sep 21 Python
详解Python函数可变参数定义及其参数传递方式
Aug 02 Python
python抽取指定url页面的title方法
May 11 Python
Python实现决策树C4.5算法的示例
May 30 Python
Python+PyQt5实现美剧爬虫可视工具的方法
Apr 25 Python
Python 变量的创建过程详解
Sep 02 Python
安装PyInstaller失败问题解决
Dec 14 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
基于jquery的返回顶部效果(兼容IE6)
2011/01/17 Javascript
js 分页全选或反选标识实现代码
2011/08/09 Javascript
网页实时显示服务器时间和javscript自运行时钟
2014/06/09 Javascript
jQuery中addClass()方法用法实例
2015/01/05 Javascript
IE8下jQuery改变png图片透明度时出现的黑边
2015/08/30 Javascript
js删除局部变量的实现方法
2016/06/25 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
模板视图和AngularJS之间冲突的解决方法
2016/11/22 Javascript
通过BootStrap-select插件 js jQuery控制select属性变化
2017/01/03 Javascript
微信小程序开发中的疑问解答汇总
2017/07/03 Javascript
利用JavaScript实现栈的数据结构示例代码
2017/08/02 Javascript
JS实现非首屏图片延迟加载的示例
2018/01/06 Javascript
Angular 项目实现国际化的方法
2018/01/08 Javascript
js统计页面上每个标签的数量实例代码
2018/05/29 Javascript
js 计算图片内点个数的示例代码
2019/04/04 Javascript
Vue 页面权限控制和登陆验证功能的实例代码
2019/06/20 Javascript
selenium+java中用js来完成日期的修改
2019/10/31 Javascript
vue动态渲染svg、添加点击事件的实现
2020/03/13 Javascript
Python isinstance判断对象类型
2008/09/06 Python
Python抓取京东图书评论数据
2014/08/31 Python
python实现连续图文识别
2018/12/18 Python
pandas的排序和排名的具体使用
2019/07/31 Python
将python2.7添加进64位系统的注册表方式
2019/11/20 Python
Python pandas 列转行操作详解(类似hive中explode方法)
2020/05/18 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
2020/06/02 Python
Python非单向递归函数如何返回全部结果
2020/12/18 Python
python中的插入排序的简单用法
2021/01/19 Python
详解CSS3弹性伸缩盒
2020/09/21 HTML / CSS
电气工程师岗位职责
2014/01/01 职场文书
2015年惩防体系建设工作总结
2015/05/22 职场文书
家长意见和建议怎么写
2015/06/04 职场文书
催款函范文
2015/06/24 职场文书
新党员入党决心书
2015/09/22 职场文书
MySQL 不等于的三种使用及区别
2021/06/03 MySQL
使用CSS实现黑白格背景效果
2022/06/01 HTML / CSS
Win11 25163.1010更新补丁KB5016904推送,测试服务验证管道(附更新修复汇总)
2022/07/23 数码科技