Quelles sont les causes d'un comportement inattendu de fermeture Lambda en Python ?

Mary-Kate Olsen
Libérer: 2024-10-21 13:10:30
original
884 Les gens l'ont consulté

What Causes Unexpected Lambda Closure Behavior in Python?

Portée des fermetures lambda Python

Comprendre le comportement des fermetures lambda en Python peut être délicat. Dans cet article, nous explorons un cas où une fonction lambda se comporte de manière inattendue, renvoyant la même valeur dans tous les cas.

Le problème :

Considérez le code suivant :

<code class="python">names = ['a', 'b', 'c']

def test_fun(name, x):
    print(name, x)

def gen_clousure(name):
    return lambda x: test_fun(name, x)

funcs1 = [gen_clousure(n) for n in names]
funcs2 = [lambda x: test_fun(n, x) for n in names]</code>
Copier après la connexion

Lors de l'appel des fonctions dans funcs1, nous obtenons le résultat attendu :

a 1
b 1
c 1
Copier après la connexion

Cependant, lors de l'appel des fonctions dans funcs2, nous obtenons un résultat inattendu :

c 1
c 1
c 1
Copier après la connexion

Le résultat attendu devrait être le même que dans le premier cas, mais à la place, nous voyons la valeur du nom de famille, « c », pour tous les cas.

L'explication :

La clé pour comprendre ce comportement réside dans la notion de fermetures. Les fermetures en Python permettent aux fonctions internes d'accéder aux variables à partir de leurs portées englobantes. Dans le premier cas (funcs1), la fonction lambda est créée dans une boucle, mais elle capture le nom de la variable de la portée englobante et le lie au nom dans la fonction lambda.

Dans le second cas (funcs2 ), cependant, la fonction lambda fait directement référence à la variable n à partir de la portée englobante sans la lier au nom dans la fonction lambda. Cela signifie que lorsque la fonction lambda est appelée, elle évalue n à ce moment-là, ce qui renvoie toujours la dernière valeur de la boucle, ce qui entraîne une sortie inattendue.

Éviter le problème :

Pour éviter ce problème et obtenir le comportement souhaité, nous devons nous assurer que la fonction lambda capture la variable de la portée englobante et la lie au nom dans la fonction lambda. Une façon de procéder consiste à envelopper la fonction lambda dans une autre fonction :

<code class="python">def makeFunc(n):
    return lambda x: x+n</code>
Copier après la connexion

La fonction lambda résultante dans makeFunc capture la valeur de n à partir de la portée englobante et la lie au nom dans la fonction lambda, atteindre le comportement souhaité.

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!

source:php
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal