博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python 闭包相关之late binding机制
阅读量:6970 次
发布时间:2019-06-27

本文共 1339 字,大约阅读时间需要 4 分钟。

先上代码:

1 def listFuc():2     temp = [lambda x: i*x for i in range(4)]3     return temp4 for singleFuc in listFuc():5     print (singleFuc(2))

上面这段代码输出结果是什么呢?

我们可能会想:listFuc这个函数是将temp这个list返回,而temp里面的元素是匿名函数,匿名函数传入参数为x,返回值为 i*x, i依次为0,1,2,3. 所以在下面这个for循环里面,将2依次传入这4个匿名函数里对x赋值,print输出返回的结果,所以结果是 0*x,1*x,2*x,3*x,即 0 2 4 6

但结果确是:

6666

为什么呢?

原因在于Python的迟绑定(late binding)机制。

闭包中内部函数的值只有在被调用时才会进行查询。

首先此匿名函数传入参数只有x,虽然返回的是i*x,但是现在传入参数中并没有i,没有对匿名函数内部的i赋值,所以相当于你申明了返回了4个函数:

lambda x: i*xlambda x: i*xlambda x: i*xlambda x: i*x
for i in range(4)这句代码起到的作用仅仅是循环4次得到4个如上面那样的匿名函数。

因此等到listFuc函数返回的lambda函数被调用时,会在附近的作用域中查询变量i的值,而在listFuc生成返回数组之后,i的值是3,因此singleFuc实际上都是:

lambda x: 3*x

所以最后输出的结果就是 6666 了

666666

那么要输出 0 2 4 6时,解决办法是在定义匿名函数时,就将i的值作为参数传入匿名函数内部:

1 def listFuc():2     temp = [lambda x,i=i: i*x for i in range(4)]3     return temp4 for singleFuc in listFuc():5     print (singleFuc(2))

这样,在每次创建匿名函数时,实际上是这样的过程:

lambda x,i=0: i*xlambda x,i=1: i*xlambda x,i=2: i*xlambda x,i=3: i*x

所以singleFuc每次传入参数2作为x的值时,i都已经被赋了值。

for i in range(4)这句代码的作用就不仅是循环4次得到4个匿名函数了,还充当了对匿名函数内部作用域变量赋值的作用
这样写可能会更好理解:
1 def listFuc():2     temp = [lambda x,y=i: y*x for i in range(4)]3     return temp4 for singleFuc in listFuc():5     print (singleFuc(2))

结果就是:

0246

参考:http://www.cnblogs.com/harelion/p/5577087.html

转载于:https://www.cnblogs.com/Anythingkk/p/9000871.html

你可能感兴趣的文章
Data Lake Analytics: 以SQL方式查询Redis数据
查看>>
elasticsearch v6.5.4配置
查看>>
关于分块思想的个人理解
查看>>
手机端车牌号码键盘的vue组件
查看>>
iOS App卡顿监控(Freezing/Lag)
查看>>
云HBase发布全文索引服务,轻松应对复杂查询
查看>>
leetcode394. Decode String
查看>>
我们如何在Linkerd 2.2里设计重试
查看>>
Java程序员月薪达到三万,需要技术水平达到什么程度?
查看>>
cross-env使用
查看>>
web移动端与Hybird开发知识整理
查看>>
用最新的 Alamofire(swift 4.1) (带参数)post方法上传图片到服务器
查看>>
我设计一个phpms框架前的准备
查看>>
小程序--语音合成tts 对接多平台(讯飞,思必驰,百度)
查看>>
Node.js文件上传
查看>>
tp5 加载 extend 类库的方法 (有命名空间和没有命名空间的调用)
查看>>
运营一款电视盒子需要注意什么?
查看>>
网络协议 9 - TCP(下)
查看>>
js中的模块化——commonjs,AMD,CMD,UMD,ES6
查看>>
Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码
查看>>