python形成闭包的必要条件_为什么Python的yield语句会形成闭包?

再加上@sepp2k的答案,你会看到这两种不同的行为,因为正在创建的lambda函数不知道从哪里得到i的值。在创建这个函数时,它只知道它必须从本地范围、封闭范围、全局范围或内置函数中获取i的值。在

在这种特殊情况下,它是一个闭包变量(封闭范围)。它的值随每次迭代而变化。在

现在来解释为什么第二个像预期的那样工作,而第一个却没有?

这是因为每次生成一个lambda函数时,生成器函数的执行就会停止,而当您调用它时,它将使用i的值。但是在第一种情况下,我们已经在调用任何函数之前将i的值提升到9。在

为了证明这一点,您可以从__closure__的单元格内容中获取i的当前值:>>> for func in test_with_yield():

print "Current value of i is {}".format(func.__closure__[0].cell_contents)

print func(9)

...

Current value of i is 0

Current value of i is 1

Current value of i is 2

Current value of i is 3

Current value of i is 4

Current value of i is 5

Current value of i is 6

...

但是,如果您将函数存储在某个地方,稍后再调用它们,您将看到与第一次相同的行为:

^{pr2}$

输出:Current value of i is 0

Current value of i is 1

Current value of i is 2

Current value of i is 3

Now value of i is 3

Now value of i is 3

Now value of i is 3

Now value of i is 3

Patrick Haugh in comments使用的示例也显示了相同的情况:sum(t(1) for t in list(test_with_yield()))

正确方法:

将i作为默认值赋给lambda,默认值是在创建函数时计算的,它们不会更改(unless it's a mutable object)。i现在是lambda函数的局部变量。在>>> def test_without_closure():

return [lambda x, i=i: x+i for i in range(10)]

...

>>> sum(t(1) for t in test_without_closure())

55

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值