Deciphering Lexical Closures in Python vs Perl
While exploring lexical closures in Javascript, the question arises about their peculiar behavior in Python. Consider the following Python code:
flist = [] for i in xrange(3): def func(x): return x * i flist.append(func) for f in flist: print f(2)
Surprisingly, it outputs "4 4 4" instead of the expected "0 2 4."
In contrast, this equivalent Perl code produces the desired result:
my @flist = (); foreach my $i (0 .. 2) { push(@flist, sub {$i * $_[0]}); } foreach my $f (@flist) { print $f->(2), "\n"; }
The Underlying Difference
The key distinction lies in how closures capture their environment.
A Python Solution
To achieve the expected behavior in Python, you need to force separate environments for each function. One solution is to create a function creater that returns a function with a different closure:
flist = [] for i in xrange(3): def funcC(j): def func(x): return x * j return func flist.append(funcC(i)) for f in flist: print f(2)
This method ensures that each function has its own distinct closure, with its own unique value of i.
The above is the detailed content of Why Does Python\'s Lexical Closure Behavior Differ from Perl\'s?. For more information, please follow other related articles on the PHP Chinese website!