Como funcionam os fechamentos lexicais?
Enquanto eu estava investigando um problema que tive com fechamentos lexicais no código Javascript, me deparei com esse problema no Python:
flist = []
for i in xrange(3):
def func(x): return x * i
flist.append(func)
for f in flist:
print f(2)
Observe que este exemplo evita conscientementelambda
. Imprime "4 4 4", o que é surpreendente. Eu esperaria "0 2 4".
Esse código Perl equivalente faz o certo:
my @flist = ();
foreach my $i (0 .. 2)
{
push(@flist, sub {$i * $_[0]});
}
foreach my $f (@flist)
{
print $f->(2), "\n";
}
"0 2 4" é impresso.
Pode explicar a diferença?
Atualizar:
O problemanão é comi
sendo global. Isso exibe o mesmo comportamento:
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)
Como mostra a linha comentada,i
é desconhecido nesse ponto. Ainda assim, imprime "4 4 4".