词汇闭包是如何工作的?

词汇闭包是如何工作的?

在研究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”。


函数式编程
浏览 432回答 3
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)

慕勒3428872

下面是如何使用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,如预期的那样。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python