Home >Backend Development >Python Tutorial >Why Does Python\'s Lexical Closure Behavior Differ from Perl\'s?

Why Does Python\'s Lexical Closure Behavior Differ from Perl\'s?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-12 16:42:10190browse

Why Does Python's Lexical Closure Behavior Differ from Perl's?

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.

  • Python: Functions created within a loop all share the closure of the loop's environment. As the loop variable i is modified, all functions reference the same modified i.
  • Perl: Functions created within a loop each have their own closure, capturing the value of i at the time they are defined.

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn