Je suis nouveau sur Python, donc c'est probablement une question simple. Le code suivant dans un fichier (module) Python m'embrouille légèrement:
if __== '__main__':
x = 1
print x
Dans d'autres langues dans lesquelles j'ai travaillé, ce code lève une exception, car la variable x
est locale à l'instruction if
et ne devrait pas exister en dehors de celle-ci. Mais ce code est exécuté et imprimé 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?
Les variables Python sont étendues à la fonction, la classe ou le module le plus à l'intérieur de leur affectation. Les blocs de contrôle tels que les blocs if
et while
ne comptent pas. Par conséquent, une variable affectée à l'intérieur d'un if
est toujours étendue à une fonction, une classe ou un module.
(Fonctions implicites définies par une expression génératrice ou une compréhension liste/ensemble/dict do compte, comme le font les expressions lambda. Vous ne pouvez pas insérer une instruction d'affectation dans aucune de celles-ci, à l'exception des paramètres lambda et des cibles de la clause for
sont des tâches implicites.)
Oui, ils sont dans la même "portée locale", et un code comme celui-ci est courant en Python:
if condition:
x = 'something'
else:
x = 'something else'
use(x)
Notez que x
n'est ni déclaré ni initialisé avant la condition, comme ce serait le cas en C ou en Java, par exemple.
En d'autres termes, Python n'a pas d'étendue au niveau du bloc. Soyez prudent, cependant, avec des exemples tels que
if False:
x = 3
print(x)
ce qui soulèverait clairement une exception NameError
.
La portée dans python suit cet ordre:
Rechercher dans la portée locale
Rechercher dans la portée de toutes les fonctions englobantes
Rechercher la portée globale
Rechercher dans les éléments intégrés
( source )
Notez que if
et les autres constructions de boucle/branchement ne sont pas répertoriés - seules les classes, fonctions et modules fournissent une étendue en Python. Par conséquent, tout élément déclaré dans un bloc if
a la même étendue que tout élément exclu en dehors du bloc. Les variables ne sont pas vérifiées au moment de la compilation, raison pour laquelle les 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.
Comme Eli l'a dit, Python ne nécessite pas de déclaration de variable. En C, vous diriez:
int x;
if(something)
x = 1;
else
x = 2;
mais, dans Python, la déclaration est implicite. Par conséquent, lorsque vous affectez à x, elle est automatiquement déclarée. C'est parce que Python est typé dynamiquement - cela ne fonctionnerait pas dans un langage à typage statique, car selon le chemin utilisé, une variable pourrait être utilisée sans être déclarée. Cela serait capturé au moment de la compilation dans un langage typé statiquement, mais avec un langage typé dynamiquement, il est autorisé.
La seule raison pour laquelle un langage de type statique est limité à l'obligation de déclarer des variables en dehors des instructions if
à cause de ce problème. Embrasser la dynamique!
Contrairement aux langages tels que C, une variable Python s'applique à l'ensemble de la fonction (ou de la classe ou du module) où elle apparaît, pas seulement dans le "bloc" le plus à l'intérieur. C'est comme si vous déclariez int x
en haut de la fonction (ou de la classe ou du module), sauf que, dans Python, vous n'avez pas à déclarer de variables.
Notez que l'existence de la variable x
est vérifiée uniquement à l'exécution, c'est-à-dire lorsque vous obtenez l'instruction print x
. Si __name__
n'était pas égal à "__main__"
, vous obtiendrez une exception: NameError: name 'x' is not defined
.
Oui. C'est également vrai pour for
scope. Mais pas des fonctions bien sûr.
Dans votre exemple: si la condition dans l'instruction if
est fausse, x
ne sera pas défini cependant.
vous exécutez ce code à partir de la ligne de commande. Par conséquent, if
conditions sont vraies et x
est défini. Comparer:
>>> if False:
y = 42
>>> y
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
y
NameError: name 'y' is not defined