-1
votes

Python, boucles et fermetures

Je suis un programmeur C / C ++ (et dans une certaine mesure de degré Java). J'apprends Python, mais je suis déconcerté à des comportements étranges (pour mes backgroung) de la langue.

J'apprends à propos de la fonction et des fermetures imbriquées (lecture "L'apprentissage de python", qui semble une très bonne source pour moi). p>

Je comprends que si j'envère un def à l'intérieur d'une boucle quand je Appelez la fonction créée, il lue la dernière valeur de la variable de boucle capturée (car elle capture par référence, en tant que programmeur C ++ le mettrait) p> xxx pré>

et exécuté le programme Le résultat est P>

for f in funcs:
  f()


2
2
2
2


9 commentaires

Votre premier code posté ne fonctionne pas comme vous vous attendez à ce que l'indentation est fausse.


Désolé, c'est une erreur de pâte de copie, mon code a raison, la modifiant maintenant


Je pense que vous avez gâché l'indentation sur funcs.append (f) . Je pourrais être hors de tri ici, mais impression (i) imprimera le dernier i généré. Dans votre cas, c'est pour i in gamme (4): et non lorsque vous avez défini la fonction. Donc, ce n'est pas étrange que vous soyez getnig cette sortie. Donc, i n'est pas congelé lors de la création de fonction, mais c'est une valeur en direct. Vous imprimez la dernière valeur connue / définie de i .


Si j'exécute le programme lorsque vous avez édité, la sortie est juste une «3» ...


Je ne peux pas non plus reproduire le deuxième exemple. Veuillez corriger les indentations et écrire le code complet afin que nous puissions vous aider!


@mrcarnivore Quel est le problème avec l'indentation? C'est juste un bloc de déclaration avec une indentation d'un niveau


@Torxed the append () appel est à l'intérieur de la boucle pour la boucle, car je dois créer une liste d'objets de fonction


@Luca oui sûr. J'ai édité votre question avant de l'éditer trois fois de suite, car j'avais supposé que c'était le cas. Cependant. impression (i) n'imprimera pas le i à partir du def f () -loop, mais plutôt le pour i in gamme (4): Funcs [i] () -Loop. Voir mon commentaire ci-dessus.


Bien que les réponses ci-dessous a déjà déjà dit, vous voudrez peut-être consulter les explications Ici et ici .


3 Réponses :


2
votes

Vos fonctions xxx

Imprimez la valeur actuelle de i .

si vous écrivez xxx

alors i est en cours de configuration sur 0,1,2,3 comme vous passez la boucle. C'est ce que pour i dans la plage (4) signifie.

si vous écrivez xxx

alors i continue avec toute la valeur qu'il avait déjà.


0 commentaires

8
votes

Tout d'abord, cela crée une liste de quatre fonctions.

funcs = []
for i in range(4):
  def f(num=i):
    print(num)
  funcs.append(f)


0 commentaires

1
votes

Il n'y a pas d'incompatibilité ici. La valeur de i dans f () dépend de la valeur de i de la portée des parents. Après avoir exécuté le premier pour i in gamme (4) i a la valeur du dernier élément de la plage , qui est 3 et donc tous les appels ultérieurs vers f () imprimeront 3

si vous exécutez xxx

vous redéfinissez la valeur de i à chaque étape d'itération, vous obtenez donc 0,1,2,3 comme les valeurs imprimées par f . Faire xxx

n'affectera pas la valeur de i et donc vous obtiendrez 3 comme valeur du i dans tous les appels de fonction


0 commentaires