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".

questionAnswers(9)

yourAnswerToTheQuestion