【发布时间】:2010-09-19 00:29:00
【问题描述】:
当我在调查 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。它打印“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”。
【问题讨论】:
-
这里有一篇关于这个问题的不错的文章。 me.veekun.com/blog/2011/04/24/gotcha-python-scoping-closures
标签: python closures lazy-evaluation late-binding python-closures