Maison >développement back-end >Tutoriel Python >Pourquoi le comportement de fermeture lexicale de Python diffère-t-il de celui de Perl ?

Pourquoi le comportement de fermeture lexicale de Python diffère-t-il de celui de Perl ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-12 16:42:10133parcourir

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

Déchiffrement des fermetures lexicales en Python vs Perl

Lors de l'exploration des fermetures lexicales en Javascript, la question se pose de leur comportement particulier en Python. Considérez le code Python suivant :

flist = []

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

for f in flist:
    print f(2)

Étonnamment, il génère "4 4 4" au lieu du "0 2 4" attendu.

En revanche, ce code Perl équivalent produit le code souhaité résultat :

my @flist = ();

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

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

La différence sous-jacente

La clé la distinction réside dans la façon dont les fermetures capturent leur environnement.

  • Python : Les fonctions créées dans une boucle partagent toutes la fermeture de l'environnement de la boucle. Lorsque la variable de boucle i est modifiée, toutes les fonctions font référence au même i modifié.
  • Perl : Les fonctions créées dans une boucle ont chacune leur propre fermeture, capturant la valeur de i au moment où elles sont définis.

Une solution Python

Pour obtenir le comportement attendu en Python, vous devez forcer environnements distincts pour chaque fonction. Une solution consiste à créer un créateur de fonction qui renvoie une fonction avec une fermeture différente :

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)

Cette méthode garantit que chaque fonction a sa propre fermeture distincte, avec sa propre valeur unique de i.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn