为了账号安全,请及时绑定邮箱和手机立即绑定

词汇闭包是如何工作的?

词汇闭包是如何工作的?

函数式编程 2019-06-16 16:10:41
词汇闭包是如何工作的?在研究Javascript代码中的词法闭包问题时,我在Python中遇到了这个问题:flist = []for i in xrange(3):     def func(x): return x * i     flist.append(func)for f in flist:     print f(2)注意,这个例子避免了lambda..它打印“44 4”,这是令人惊讶的。我希望“0 2 4”。这个等价的Perl代码是正确的:my @flist = ();foreach my $i (0 .. 2){     push(@flist, sub {$i * $_[0]});}foreach my $f (@flist){     print $f->(2), "\n";}打印“0 2 4”。你能解释一下区别吗?最新情况:问题不是带着i是全球性的。这将显示相同的行为:flist = []def outer():     for i in xrange(3):         def inner(x): return x * i         flist.append(inner)outer()#~ print i   # commented because it causes an errorfor f in flist:     print f(2)如注释行所示,i在这一点上是未知的。尽管如此,它还是打印了“4 4 4”。
查看完整描述

3 回答

?
米脂

TA贡献1836条经验 获得超3个赞

循环中定义的函数一直在访问同一个变量。i当它的价值改变的时候。在循环的末尾,所有函数都指向相同的变量,该变量保存了循环中的最后一个值:效果就是在示例中报告的结果。

为了评价i并使用它的值,常见的模式是将其设置为参数默认值:def语句,从而冻结循环变量的值。

预期的工作如下:

flist = []for i in xrange(3):
    def func(x, i=i): # the *value* of i is copied in func() environment
        return x * i
    flist.append(func)for f in flist:
    print f(2)


查看完整回答
反对 回复 2019-06-16
?
慕勒3428872

TA贡献1848条经验 获得超6个赞

下面是如何使用functools库(在提出问题时,我不确定它是否可用)。

from functools import partial

flist = []def func(i, x): return x * ifor i in xrange(3):
    flist.append(partial(func, i))for f in flist:
    print f(2)

输出0 2 4,如预期的那样。


查看完整回答
反对 回复 2019-06-16
  • 3 回答
  • 0 关注
  • 431 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信