Podczas badania problemu, który miałem z zamknięciami leksykalnymi w kodzie JavaScript, napotkałem ten problem w Pythonie:
flist = []
for i in xrange(3):
def func(x): return x * i
flist.append(func)
for f in flist:
print f(2)
Zauważ, że ten przykład świadomie unika lambda
. Drukuje "4 4 4", co jest zaskakujące. Spodziewałbym się „0 2 4”.
Ten równoważny kod w Perlu robi to dobrze:
my @flist = ();
foreach my $i (0 .. 2)
{
push(@flist, sub {$i * $_[0]});
}
foreach my $f (@flist)
{
print $f->(2), "\n";
}
Drukowane jest "0 2 4".
Czy możesz wyjaśnić różnicę?
Aktualizacja:
Problem nie jest z i
bycia globalnym. To wyświetla to samo zachowanie:
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)
Jak pokazuje skomentowana linia, i
w tym momencie nie jest znana. Mimo to wypisuje "4 4 4".