web-dev-qa-db-fra.com

Portée dans Python 'pour' boucles

Je ne parle pas des règles de portée de Python; Je comprends généralement comment le cadrage fonctionne dans Python pour les boucles. Ma question est pourquoi les décisions de conception ont été prises de cette manière. Par exemple ( sans jeu de mots):

for foo in xrange(10):
    bar = 2
print(foo, bar)

Ce qui précède sera imprimé (9,2).

Cela me semble étrange: "foo" ne fait que contrôler la boucle, et "bar" a été défini à l'intérieur de la boucle. Je peux comprendre pourquoi il peut être nécessaire que "bar" soit accessible en dehors de la boucle (sinon, les fonctionnalités des boucles seraient très limitées). Ce que je ne comprends pas, c'est pourquoi il est nécessaire que la variable de contrôle reste dans la portée une fois la boucle terminée. D'après mon expérience, cela encombre tout l'espace de noms global et rend plus difficile la recherche d'erreurs qui seraient capturées par des interprètes dans d'autres langues.

154
chimeracoder

La réponse la plus probable est que la grammaire reste simple, que l’adoption n’est pas une pierre d'achoppement et que beaucoup ont été satisfaits de ne pas avoir à lever l'ambiguïté de l'étendue à laquelle appartient un nom lors de son affectation dans une construction en boucle. Les variables ne sont pas déclarées dans une étendue, elle est impliquée par l'emplacement des instructions d'affectation. Le mot clé global existe uniquement pour cette raison (pour indiquer que l'assignation est effectuée dans une étendue globale).

Mettre à jour

Voici une bonne discussion sur le sujet: http://mail.python.org/pipermail/python-ideas/2008-October/002109.html

Les précédentes propositions visant à créer des variables de boucle for locales à la boucle étaient tombées sur le problème du code existant reposant sur le fait que la variable de boucle conservait sa valeur après avoir quitté la boucle, ce qui semble être considéré comme une fonctionnalité souhaitable.

En bref, vous pouvez probablement blâmer la Python communauté: P

93
Jeremy Brown

Python n'a pas de blocs, contrairement à d'autres langages (tels que C/C++ ou Java). Par conséquent, l'unité de cadrage dans Python est une fonction.

56
atzz

Un cas vraiment utile pour cela est lorsque vous utilisez enumerate et que vous voulez le nombre total à la fin:

for count, x in enumerate(someiterator, start=1):
    dosomething(count, x)
print "I did something {0} times".format(count)

Est-ce nécessaire? Non, mais c'est bien pratique.

Une autre chose à prendre en compte: dans Python 2, les variables dans les interprétations de liste sont également divulguées:

>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> x
9

Mais la même chose ne s'applique pas à Python 3.

37
carl

Si vous avez une instruction break dans la boucle (et que vous souhaitez utiliser la valeur d'itération ultérieurement, par exemple pour reprendre, indexer ou donner un statut), cela vous enregistre une ligne de code et une affectation, ce qui est pratique.

2
Mac

L'une des principales influences de Python est ABC , un langage développé aux Pays-Bas pour enseigner des concepts de programmation aux débutants. Python's Son créateur, Guido van Rossum, a travaillé sur ABC pendant plusieurs années dans les années 80. Je ne sais presque rien sur ABC, mais comme il est destiné aux débutants, je suppose qu'il doit avoir un nombre limité d'étendues, un peu comme les premiers BASIC.

1
kindall

Pour commencer, si les variables étaient locales aux boucles, ces boucles seraient inutiles pour la plupart des programmes en situation réelle.

Dans la situation actuelle:

# Sum the values 0..9
total = 0
for foo in xrange(10):
    total = total + foo
print total

donne 45. Voyons maintenant comment fonctionne l’affectation en Python. Si les variables de boucle étaient strictement locales:

# Sum the values 0..9?
total = 0
for foo in xrange(10):
    # Create a new integer object with value "total + foo" and bind it to a new
    # loop-local variable named "total".
    total = total + foo
print total

donne 0, car total à l'intérieur de la boucle après l'affectation n'est pas la même variable que total à l'extérieur de la boucle. Ce ne serait pas un comportement optimal ou attendu.

1
Kirk Strauser