Python-词汇闭包如何工作?
当我研究Java代码中的词法闭包问题时,我在Python中遇到了这个问题:
flist = []for i in xrange(3):
def func(x): return x * i
flist.append(func)
for f in flist:
print f(2)
请注意,此示例应避免使用lambda。它打印“ 4 4 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 error
for f in flist:
print f(2)
如注释行所示,i在这一点上未知。仍然打印“ 4 4 4”。
回答:
实际上,Python的行为符合定义。创建了三个单独的函数,但是每个函数都封闭了定义它们的环境 -在这种情况下,是全局环境(如果将循环放在另一个函数内部,则为外部函数的环境)。不过,这确实是问题所在-在这种环境下,i发生了变异,并且所有闭包都引用相同的i。
这是我能想到的最佳解决方案-创建一个函数创建器,然后调用它。这将为所创建的每个函数强制使用不同的环境,每个函数具有不同的i。
flist = []for i in xrange(3):
def funcC(j):
def func(x): return x * j
return func
flist.append(funcC(i))
for f in flist:
print f(2)
当您混合副作用和功能编程时,就会发生这种情况。
以上是 Python-词汇闭包如何工作? 的全部内容, 来源链接: utcz.com/qa/400038.html