Comment gérer les problèmes de portée variable dans les fermetures Lambda non imbriquées ?

Barbara Streisand
Libérer: 2024-10-21 13:10:03
original
605 Les gens l'ont consulté

How to Handle Variable Scoping Issues in Non-Nested Lambda Closures?

Portée des fermetures Python Lambda

Problème

Encapsuler des variables dans des fermetures pour les supprimer des signatures de fonction est une technique souvent utilisée pour une structuration efficace du code. Cependant, dans le cas de lambdas non imbriquées, la fermeture conserve la valeur finale de la variable, ce qui entraîne des problèmes lors de la tentative d'accès à des valeurs spécifiques basées sur la variable itérative.

Considérez l'extrait de code fourni :

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]

# Expected output for funcs1
for f in funcs1:
    f(1)

# Unexpected output for funcs2 (returns last element for all cases)
for f in funcs2:
    f(1)
Copier après la connexion

Comprendre la raison de cet écart est crucial pour une utilisation efficace des fermetures.

Réponse

Le concept fondamental dans cette situation est portée variable dans les fermetures . Les fermetures contiennent intrinsèquement les noms de variables plutôt que leurs valeurs. Cela signifie que l'évaluation de la variable se produit au début de l'exécution de lambda, plutôt qu'au moment de la définition de lambda.

Dans le cas de funcs2, lorsque vous exécutez lambda x : test_fun(n, x), la variable n n’est pas évalué lors de la définition lambda. Au lieu de cela, l'évaluation n'a lieu que lors de l'appel lambda. À ce stade, n contient la dernière valeur de la boucle (qui est « c » dans ce cas). Par conséquent, la fonction f utilise toujours « c » comme valeur de n, quelle que soit l'entrée x.

Pour résoudre ce problème et obtenir la fonctionnalité souhaitée, la variable n doit être capturée dans la portée de la fonction lambda. Ceci peut être réalisé en passant la variable comme argument au lambda, comme illustré dans ce qui suit :

funcs2 = [lambda x: test_fun(n, x) for n in names if 2 > 0]
Copier après la connexion

En incluant cette instruction if supplémentaire qui est toujours vraie, nous forçons le lambda pour prendre la valeur de n comme argument, garantissant le comportement personnalisé attendu dans tous les cas.

Alternative avec Wrapped Lambda

Alternativement, vous pouvez envelopper le lambda non imbriqué dans un imbriqué fonction, empêchant efficacement l’accès aux variables non déclarées dans la portée. Le code suivant illustre cette approche :

def makeFunc(n):
    return lambda x: x+n

stuff = [makeFunc(n) for n in [1, 2, 3]]

for f in stuff:
    print(f(1))
Copier après la connexion

Ici, la variable n est capturée dans la fonction makeFunc, garantissant une portée appropriée au sein du lambda.

Conclusion

Compréhension et la gestion de la portée des variables dans les fermetures est essentielle pour une conception et un débogage efficaces du code. Les principaux points à retenir sont :

  • Les fermetures contiennent des noms de variables, pas des valeurs
  • L'évaluation des variables se produit lors de l'exécution de lambda
  • Pour capturer les variables, transmettez-les comme arguments ou enveloppez-les le lambda dans une autre fonction

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
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!