Je suis nouveau sur Python, c'est donc probablement une question de portée simple. Le code suivant dans un fichier Python (module) m'embrouille légèrement:
if __name__ == '__main__':
x = 1
print x
Dans d'autres langages dans lesquels j'ai travaillé, ce code lèverait une exception, car la x
variable est locale à l' if
instruction et ne devrait pas exister en dehors d'elle. Mais ce code s'exécute et imprime 1. Quelqu'un peut-il expliquer ce comportement? Toutes les variables créées dans un module sont-elles globales / disponibles pour l'ensemble du module?
if
déclaration ci-dessus n'est pas vraie (c'est-à-__name__
dire qu'elle ne l' est pas'__main__'
, par exemple lorsque vous importez le module au lieu de l'exécuter au niveau supérieur), alors ellex
n'aura jamais été liée et laprint x
déclaration suivante jettera unNameError: name 'x' is not defined
.Réponses:
Les variables Python sont limitées à la fonction, à la classe ou au module le plus interne auquel elles sont affectées. Les blocs de contrôle comme
if
et leswhile
blocs ne comptent pas, donc une variable assignée à l'intérieur d'unif
est toujours étendue à une fonction, une classe ou un module.(Fonctions implicites définies par une expression de générateur ou d'une liste / set / dict compréhension faire nombre, tout comme lambda expressions. Vous ne pouvez pas farcir une instruction d'affectation dans l' un de ceux, mais les paramètres lambda et les
for
objectifs de la clause sont cession implicite.)la source
Oui, ils sont dans la même "portée locale", et en fait, un code comme celui-ci est courant en Python:
Notez que ce
x
n'est pas déclaré ou initialisé avant la condition, comme ce serait en C ou Java, par exemple.En d'autres termes, Python n'a pas d'étendues au niveau du bloc. Soyez prudent, cependant, avec des exemples tels que
ce qui soulèverait clairement une
NameError
exception.la source
La portée en python suit cet ordre:
Rechercher la portée locale
Rechercher l'étendue de toutes les fonctions englobantes
Rechercher la portée mondiale
Rechercher les intégrés
( source )
Notez que
if
et d'autres constructions en boucle / ramification ne sont pas répertoriées - seules les classes, fonctions et modules fournissent une portée en Python, donc tout ce qui est déclaré dans unif
bloc a la même portée que tout ce qui a été effacé en dehors du bloc. Les variables ne sont pas vérifiées au moment de la compilation, c'est pourquoi d'autres langages lèvent une exception. En python, tant que la variable existe au moment où vous en avez besoin, aucune exception ne sera levée.la source
Comme l'a dit Eli, Python ne nécessite pas de déclaration de variable. En C, vous diriez:
mais en Python, la déclaration est implicite, donc lorsque vous l'assignez à x, elle est automatiquement déclarée. C'est parce que Python est typé dynamiquement - cela ne fonctionnerait pas dans un langage typé statiquement, car selon le chemin utilisé, une variable pourrait être utilisée sans être déclarée. Cela serait intercepté au moment de la compilation dans une langue typée statiquement, mais avec une langue typée dynamiquement, cela est autorisé.
La seule raison pour laquelle un langage typé statiquement se limite à devoir déclarer des variables en dehors des
if
instructions à cause de ce problème. Embrassez la dynamique!la source
Contrairement aux langages tels que C, une variable Python est à la portée de l'ensemble de la fonction (ou classe ou module) où elle apparaît, et pas seulement dans le "bloc" le plus intérieur. C'est comme si tu avais déclaré
int x
en haut de la fonction (ou classe, ou module), sauf qu'en Python vous n'avez pas à déclarer de variables.Notez que l'existence de la variable
x
n'est vérifiée qu'au moment de l'exécution, c'est-à-dire lorsque vous accédez à l'print x
instruction. Si__name__
n'égalait"__main__"
alors vous faire une exception:NameError: name 'x' is not defined
.la source
Oui. C'est également vrai pour la
for
portée. Mais pas de fonctions bien sûr.Dans votre exemple: si la condition dans l'
if
instruction est fausse,x
elle ne sera cependant pas définie.la source
vous exécutez ce code à partir de la ligne de commande, les
if
conditions sont donc vraies etx
définies. Comparer:la source
Et notez que puisque les types Python ne sont vérifiés qu'au moment de l'exécution, vous pouvez avoir du code comme:
Mais j'ai du mal à penser à d'autres façons dont le code fonctionnerait sans erreur en raison de problèmes de type.
la source