python 类的执行中保部存值_Python 闭包相关之late binding机制

1def listFuc():2 temp = [lambda x: i*x for i in range(4)]3 returntemp4 for singleFuc inlistFuc():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

但结果确是:

6

6

6

6

为什么呢?

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

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

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

lambda x: i*x

lambda x: i*x

lambda x: i*x

lambda 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的值作为参数传入匿名函数内部:

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

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

lambda x,i=0: i*x

lambda x,i=1: i*x

lambda x,i=2: i*x

lambda x,i=3: i*x

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

for i in range(4)这句代码的作用就不仅是循环4次得到4个匿名函数了,还充当了对匿名函数内部作用域变量赋值的作用

这样写可能会更好理解:

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

结果就是 :

0

2

4

6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值