python闭包两种写法_浅析Python闭包
一、什么是闭包python
在介绍闭包概念前,咱们先来看一段简短的代码数组
def sum_calc(*args):defwrapper():
sum=0for n inargs:
sum+=n;returnsumreturn wrapper
很显然,这段代码定义了一个名为sum_calc的函数,但和定义的普通函数不一样的是这个函数体的内部又定义了一个名为wrapper的函数,而且sum_calc函数的返回值是内部定义wrapper函数。闭包
如今咱们开始来调用sum_calc函数,看看会出现哪些有趣的事情app
>>> f = sum_calc(1, 2, 3, 4, 5)>>>f.wrapper at 0x0000025693AC2D30>
>>>f()
15
从运行结果来看,当咱们调用sum_calc时,返回的并非求和结果,而是内部定义的求和函数。函数
继续调用sum_calc返回函数时,才真正计算出求和的结果。spa
当咱们继续调用一次sum_calc,传入相同参数code
>>> f1 = sum_calc(1, 2, 3, 4, 5)>>> f2 = sum_calc(1, 2, 3, 4, 5)>>> f1 ==f2
False
>>> f1()
15
>>> f2()
15
每次调用sum_calc,即便传入相同的参数,两次返回的对象不一样,且f1()和f2()的结果互不影响。对象
在这个例子中,咱们在sum_calc函数中定义的wrapper函数,wrapper函数能够引用外部函数sum_calc的参数和局部变量,当sum_calc返回函数wrapper时,相关参数保存在返回的函数中,能够被返回的函数继续使用,咱们把这种状况称为“闭包”。blog
参考维基百科,对“闭包”进行更严谨的解释:io
在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即便已经离开了创造它的环境也不例外。因此,有另外一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时能够有多个实例,不一样的引用环境和相同的函数组合能够产生不一样的实例。
二、闭包陷阱
defmy_fun():
fs=[]for i in range(0, 3):deff():return i*i
fs.append(f)return fs
f1, f2, f3 = count()
在上面的例子中,每次循环,都建立了一个新的函数,而后,把建立的3个函数都放在列表中返回。
咱们可能认为,f1()、f2()、f3()结果是0、一、4,但实际结果是4
>>>f1()4
>>>f2()4
>>>f3()4
这个例子能够说是典型的错误使用闭包的案例,my_fun返回的并非一个闭包函数,而是一个包含三个闭包函数的一个列表。
在返回闭包列表fs以前for循环的变量的值已经发生改变了,循环内闭包函数仅声明了本身计算方式,并不会当即使用当前i的值进行计算。只有在真正调用闭包函数时,才会真正的执行闭包函数内的计算,而此时存放的i的值已是2,因此f1()、f2()、f3()的结果是4而不是我在以前期待的0、一、4。
通过上面的分析,咱们得出下面一个重要的经验:返回闭包中不要引用任何循环变量,或者后续会发生变化的变量。
正确写法
def my_fun(*args):
L=[]for i in range(3):def wrapper(_i =i):return _i *_i
L.append(wrapper)return L
三、闭包实现机制
闭包比普通的函数多了一个 __closure__ 属性,该属性记录着自由变量内容。当闭包被调用时,系统就会根据该地址找到对应的自由变量,完成总体的函数调用
还以 sum_calc() 为例,当其被调用时,能够经过 __closure__ 属性获取自由变量(也就是程序中的 args参数)内容,例如:
def sum_calc(*args):defwrapper():
sum=0for n inargs:
sum+=n;returnsumreturn wrapper
输出结果:
>>> f1 = sum_calc(1, 2, 3, 4, 5)>>> f1.__closure__(,)
>>> f1.__closure__[0].cell_contents
(1, 2, 3, 4, 5)
能够看到,显示的内容是一个tuple类型,这就是f1中自由变量args的值。还能够看到,__closure__ 属性的类型是一个元组,这代表闭包能够支持多个自由变量的形式。
python闭包两种写法_浅析Python闭包相关推荐
- python是一种解释型语言_解释型语言python
摘要 计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序.由于翻译方式的不同,习惯上我们大致把高级语言分为两类,即编译型语言和解释型 ...
- anaconda中的python如何进行关联分析_浅析python,PyCharm,Anaconda三者之间的关系
一.它们是什么? Python是一种跨平台的计算机程序设计语言,简单来说,python就是类似于C,Java,C++等,一种编程语言. 2.Anaconda Anaconda指的是一个开源的Pytho ...
- python字典嵌套字典构造_浅析python 字典嵌套
为什么需要嵌套? 有时候,需要将一系列字典存储在列表中,或将列表作为值存储在字典中,这称为嵌套 .你可以在列表中嵌套字典.在字典中嵌套列表甚至在字典中嵌套字典. 字典列表 例如:字典alien_0包含 ...
- python闭包的延迟绑定_浅析Python的闭包和延迟绑定
def multipliers(): return [lambda x : i * x for i in range(4)] print [m(2) for m in multipliers()] 你 ...
- python 多条件 选择 算法_浅析Python中的多条件排序实现
多条件排序及itemgetter的应用曾经客户端的同事用as写一大堆代码来排序,在得知Python排序往往只需要一行,惊讶无比,遂对python产生浓厚的兴趣. 之前在做足球的积分榜的时候需要用到多条 ...
- python派落塔问题_浅析python递归函数和河内塔问题
关于递归函数: 函数内部调用自身的函数. 以n阶乘为例: f(n) = n ! = 1 x 2 x 3 x 4 x...x(n-1)x(n) = n x (n-1) ! def factorial(n ...
- python是哪种动物_基于Python的动物识别专家系统
1. 利用pyqt5来设计专家系统的界面. 如下图一: 图一 起始界面 相应的运行过程的界面,如图二: 图二 相应的运行过程界面 2. 设置规则文本 guizhe.txt 有毛发 哺乳动物 有奶 哺乳 ...
- python合并两个字符串_【Python进阶】2.14 合并拼接字符串
2.14 合并拼接字符串 问题 你想将几个小的字符串合并为一个大的字符串 解决方案 如果你想要合并的字符串是在一个序列或者 iterable 中,那么最快的方式就是使用 join() 方法.比如: & ...
- python合并两个数据集_在Python中合并两个数据集
我有两组x-y数据,它们的x值应该合并.为了说明这一点,第一组如下所示:0.5;3.4 0.8;3.8 0.9;1.2 1.3;1.1 1.9;2.3 第二盘是这样的: ^{pr2}$ 数据在两个单独 ...
最新文章
- 一文概览深度学习中的激活函数
- PPT绘制示意图视频+文字版本-一篇就学会
- 恢复删除的Linux文件
- 使用Notepad++ 删除非连续的列内容操作实例
- postgres-#和postgres=#
- SAP S/4HANA分层存储仓库原理介绍LREP - Layered Repository
- html盒模型向上浮动,HTML5盒模型、浮动和定位
- Eclipse中的集成Git插件删除线上远程分支
- 为什么说IT科技公司应该留住35岁员工?
- 人人开源项目文档_为什么图对于您的开源项目文档至关重要
- 实时检测input的长度_目标检测——TinyYOLOv3
- LeetCode 424. 替换后的最长重复字符(双指针+滑动窗口)
- 小米2s Android pie,Android 9 Pie什么时候升级?小米MIX 2S抢先体验!
- 【Python实例第11讲】文本的核外分类
- SQLSERVER2000 存储过程与ORACLE存储过程对比
- radio切换控制div显示_【原】react做tab切换的几种方式
- Chi-Plots和Kendall Plots
- Unity-黑暗之魂复刻-角色摄相机
- WireShark 分析RTP丢包率
- FPGA VIVADO仿真详解 TEST BENCH