Maison >développement back-end >Tutoriel Python >Pourquoi les fonctions définies dans les boucles renvoient-elles souvent la même valeur et comment cela peut-il être corrigé ?

Pourquoi les fonctions définies dans les boucles renvoient-elles souvent la même valeur et comment cela peut-il être corrigé ?

DDD
DDDoriginal
2025-01-01 08:13:10860parcourir

Why Do Functions Defined in Loops Often Return the Same Value, and How Can This Be Fixed?

Création de fonctions dans des boucles : résolution des problèmes de liaison tardive

Lorsque vous essayez de définir des fonctions individuelles dans une boucle, il est courant de rencontrer le problème où toutes les fonctions renvoient la même valeur même si elles sont destinées à représenter des résultats uniques. Ce phénomène, connu sous le nom de liaison tardive, se produit car les fonctions ne reçoivent pas leurs arguments tant qu'elles ne sont pas appelées.

Considérons l'exemple suivant utilisant une boucle for :

functions = []
for i in range(3):
    def f():
        return i
    functions.append(f)

Telle qu'elle est écrite, chaque fonction recherche sa valeur correspondante de i au moment où il est appelé. Cependant, une fois la boucle exécutée, toutes les fonctions feront référence à la valeur finale de i (2), ce qui donnera le résultat suivant :

print([f() for f in functions])
# Expected: [0, 1, 2]
# Actual: [2, 2, 2]

Solution : application de la liaison anticipée

Pour résoudre ce problème, il est nécessaire de forcer la liaison anticipée en attribuant des arguments aux fonctions au moment de la définition plutôt qu'au moment de l'appel. Ceci peut être réalisé en ajoutant un argument par défaut à la définition de la fonction :

functions = []
for i in range(3):
    def f(i=i):
        return i
    functions.append(f)

L'argument par défaut (dans ce cas, i=i) est évalué lorsque la fonction est définie, pas lorsqu'elle est appelée. Cela garantit que chaque fonction conserve sa valeur d'argument unique, produisant le résultat souhaité :

print([f() for f in functions])
# Output: [0, 1, 2]

Approche alternative utilisant la fermeture

Si des inquiétudes surviennent quant au potentiel d'arguments supplémentaires à transmettre à la fonction, une approche plus élaborée peut être implémentée à l'aide de fermetures :

def make_f(i):
    def f():
        return i
    return f

Dans ce scénario, une fabrique de fonctions (make_f) est créé. Dans la boucle, la fonction renvoyée par make_f est affectée à la variable f au lieu d'appeler directement def f():. Cette approche garantit que chaque fonction conserve sa valeur d'argument exclusive, comme dans la première solution de liaison.

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