Wie funktionieren lexikalische Verschlüsse?

Während ich ein Problem mit lexikalischen Closures im Javascript-Code untersuchte, stieß ich in Python auf folgendes Problem:

flist = []

for i in xrange(3):
    def func(x): return x * i
    flist.append(func)

for f in flist:
    print f(2)

Beachten Sie, dass dieses Beispiel achtsam vermeidetlambda. Es wird "4 4 4" gedruckt, was überrascht. Ich würde mit "0 2 4" rechnen.

Dieser äquivalente Perl-Code macht es richtig:

my @flist = ();

foreach my $i (0 .. 2)
{
    push(@flist, sub {$i * $_[0]});
}

foreach my $f (@flist)
{
    print $f->(2), "\n";
}

"0 2 4" wird gedruckt.

Können Sie bitte den Unterschied erklären?

Aktualisieren:

Das Problemist nicht miti global sein. Dies zeigt das gleiche Verhalten:

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)

Wie die kommentierte Zeile zeigt,i ist zu diesem Zeitpunkt unbekannt. Trotzdem wird "4 4 4" gedruckt.

Antworten auf die Frage(9)

Ihre Antwort auf die Frage