python中闭包不是立刻执行_一道神奇的Python面试题,你会吗?

无意间,看到这么一道Python面试题:以下代码将输出什么?

def testFun():

temp = [lambda x : i*x for i in range(4)]

return temp

for everyLambda in testFun():

print (everyLambda(2))

脑中默默一想,这还用说么,肯定是:

0

2

4

6

最后一看答案,竟然是:

6

6

6

6

于是带着怀疑的心态(其实是不服输,不认错),打开编辑器,快速一敲,果然是:

怀疑了人生半天,本来还想黑,WTF Python…然后才想通是自己太生疏......

最后发现原因竟是:Python 的闭包的后期绑定导致的 late binding。

这意味着在闭包中的变量是在内部函数被调用的时候被查找,所以当任何testFun() 返回的函数被调用,i 的值是在它被调用时的周围作用域中查找。

也就是说无论哪个返回的函数被调用,for 循环都已经完成了,i 最后的值是 3,因此,每个返回的函数 testFun 的值都是 3。

因此一个等于 2 的值被传递进以上代码,它们将返回一个值 6 (比如:3 x 2)。

究竟如何才能实现出这样的结果呢?

0

2

4

6

想了想,若能立即绑定参数,或者直接不用闭包总该行吧,用另一种方式避免 i 的改写。

回忆了之前所学知识,最后酝酿出了四种解决方案。

第一种:创建一个闭包,通过使用默认参数立即绑定它的参数

def testFun():

temp = [lambda x, i=i: i * x for i in range(4)]

return temp

for everyLambda in testFun():

print(everyLambda(2))

第二种:使用functools.partial 函数,把函数的某些参数(不管有没有默认值)给固定住(也就是相当于设置默认值)

from functools import partial

from operator import mul

def testFun():

return [partial(mul, i) for i in range(4)]

for everyLambda in testFun():

print(everyLambda(2))

第三种:优雅的写法,直接用生成器

def testFun():

return (lambda x, i=i: i * x for i in range(4))

for everyLambda in testFun():

print(everyLambda(2))

第四种:利用yield的惰性求值的思想

def testFun():

for i in range(4):

yield lambda x: i * x

for everyLambda in testFun():

print(everyLambda(2))

最终运行结果:

有了解决方案后,又陷入了怀疑自己,这个题目究竟是考察的是什么?是在考面试者闭包相关知识以及Python 的闭包的后期绑定问题么?

若将题目改成:以下代码输出的结果是(0,2,4,6)么?如果不是,你将会怎么做,让它变成(0,2,4,6)?这样会不会更有意思点呢?欢迎大家出妙招,看究竟有多少招?(哈哈哈!!!)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305067.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.net 中通用的formatstring格式符整理

格式化日期和数字的字符串经常要用到这个, 就把帮助里面的东西大概整理了一些列在这里了. 下表描述了用来格式化 DateTime 对象的标准格式说明符。 格式说明符名称说明d短日期模式显示由与当前线程关联的 DateTimeFormatInfo.ShortDatePattern 属性定义的模式或者由指定格式提供…

linux内核分为子系统,Linux内核内存管理子系统分析【转】

还是那张熟悉的老图:Linux内核子系统简介(由七个部分组成)Linux内存管理模型:1. 内存管子系统职能:1> 管理虚拟地址与物理地址的映射2> 管理物理内存的分配2. 地址映射管理1> 虚拟地址空间分布:linux采用的是一种虚拟地…

python打包成安装包_把 python 程序打包成 egg 或者 whl 安装包

1.1 安装setuptools 首先要安装setuptools工具。Debian/Ubuntu下可以直接使用apt安装: $ sudo apt-get install python-setuptools 或者通过pip安装: $ pip install setuptools 更新setuptools: $ pip install --upgrade setuptools 或者下载…

关于C#事件处理函数中的参数(object sender, EventArgs e)

1、是事件源,表示触发事件的那个组件 如(button/label/listview...),比如说你单击button,那么sender就是button2、EventArgs是事件参数,它用来辅助你处理事件比如说你用鼠标点击窗体,那么EventArgs是会包含点击的位置…

spss22.0统计分析从入门到精通_数据分析最全资料:SPSS/MATLAB/SQL/SAS/EXCEL经典教材+视频教程,快速入门!...

可以说当今社会数据就是力量。数据分析能力已经成为各个行业必备的技能,如果能熟练掌握数据分析技能,不管是留学申请还是以后的就业,都会是一个很大的加分项。但是目前国内很少有高校专门开设数据分析课程,想要掌握技能大部分要靠…

可反复擦写5万次的手写板,竟然还能用橡皮擦能清除屏幕!

作为一名文艺青年,平时写字画画是我的一大爱好。 心情不错,来个创作! 还记得我们之前介绍过的Boogie Board电子手写板吗? 小木用的就是它。 虽然好用,只不过有时候不小心画错了,只能重新来。 伤心啊…… 不…

普通用户杜绝不请自来的邮件对策

1、给自己的信箱起个“复杂用户名”:许多人习惯用自己姓名的拼音作为用户名,但一般过于简单,这样被垃圾邮件制造者捕捉到的机率很高。因此在申请邮箱时,不妨起个保护性强一点的用户名,比如英文和数字的组合,尽量长一点…

[Abp 源码分析]权限验证

点击上方蓝字关注我们0.简介Abp 本身集成了一套权限验证体系,通过 ASP.NET Core 的过滤器与 Castle 的拦截器进行拦截请求,并进行权限验证。在 Abp 框架内部,权限分为两块,一个是功能(Feature),一个是权限项(Permissio…

cocoscreator editbox 只允许数字_《Cocos Creator游戏实战》做一个数字调节框

当玩家购买道具的时候,一个个买可能会比较麻烦,用数字调节框的话玩家一次性就可以买好几十个了(钱够的话)。运行效果如下:Cocos Creator版本:2.2.0公号"All Codes"后台回复"数字调节框",获取该项目…

linux自动应答,08. 创建 ks.cfg自动应答文件

Kiskstart 安装步骤比较 Cobbler 自动化部署复杂些,众所周知,随着时间推移,行业会逐步的降低软件操作难度以作为软件提升的标志,于是 Cobbler 产生掩盖或者帮操作者完成了许多工作,于是使用就更简单。但是使用 Kisksta…

python类变量共享吗_第7.12节 可共享的Python类变量

第7.12节 可共享的Python类变量一、 引言在上节已经引入介绍了类变量和实例变量,类体中定义的变量为类变量,默认属于类本身,实例变量是实例方法中定义的self对象的变量,对于每个实例都是独有数据,而类变量是该类所有…

为什么一流成功人士的闹钟都定在早晨5:57?

对很多人来说,早晨时分是一天中最匆忙的时段。近年来,我在研究人们如何利用时间的过程中发现,市场上铺天盖地的媒体教你如何利用早晨的时间。 美国国家睡眠基金会发布的一项睡眠调查结果显示,在工作日的早晨,30-50岁的…

命令行小技巧

我们平时使用Linux的时候经常遇到这样一个问题,举例有这样一种情况:执行命令 $ cp /etc/apt/sources.list /etc/apt/sources.list.bak 这里面有个问题,明明 /etc/apt/sources 这几个字都是一样的,为什么要打两遍?这样的…

统计学习导论_统计机器学习之扫盲导论篇

机器学习之扫盲导论篇来都来了,不关注一下吗??人工智能是当下最火的词,而机器学习就是它的灵魂。现在超级多搞金融的人已经用到很深的机器学习模型了,更别提互联网企业的大佬们了,比如:(这是一篇…

linux环境下创建postgis数据库,linux下搭建postgresql、postgis、pg_pathman环境步骤详解...

操作系统:centOS6.6安装postgreSQL9.6.2安装命令:./postgresql-9.6.3-2-linux-x64.run之后按照图形界面操作安装,语言选择zh_CN UTF-8安装geos-3.6.0(会报错,暂时不用管)安装命令:tar xjvfgeos-3.6.0.tar.bz2cd geos-3…

[Abp 源码分析]异常处理

点击上方蓝字关注我们Abp 框架本身针对内部抛出异常进行了统一拦截,并且针对不同的异常也会采取不同的处理策略。在 Abp 当中主要提供了以下几种异常类型:异常类型描述AbpExceptionAbp 框架定义的基本异常类型,Abp 所有内部定义的异常类型都继…

phpstorm设置 打开文件所在目录_PDF文件在线分享并设置打开次数

公司有一些重要的PDF文档,怎么才能防止外泄?如何加密PDF文件防止被人复制了?怎样让PDF不能被别人拷贝啊? 这些问题困扰了一部分想让别人看pdf内容又担心别人泄露的人。本文用maipdf网站的例子来进行设置。首先我们打开maipdf的网站…

荐号 | 11个人工智能与大数据相关的个人、企业优质号

AlphaGo Zero都会自学了,作为刚刚步入AI大门的我们,应该如何选择合适自己的知识平台呢?今天小编为你甄选了几个高质量的技术公众号。 这些号更多的不是讲授枯燥的理论,而是从行业资讯、一线技术、应用案例、职场发展等多个角度分享…

以表达式作为参数传入SQL的存储过程中去

在开发过程中,需要把一句Sql 的expression作为一个参数传入Procedure中去。 在asp.net中,一个Search的动作,把用户所操作的搜索条件写成了一句表达式,现只需要把这句表达式传入存储过程中去,与存储过程中的Sql的Select…

围棋中的数学原理

围棋一向被誉为是人类大脑智慧的专利,围棋的走法,几乎和宇宙中原子数量相同,甚至更多,每回合有250种可能,一盘棋可以长达150个回合,共有1后面再加360个0种下法,这样的计算量,对计算机…