La première et la question évidente est pourquoi?
Il existe quelques situations dans lesquelles les variables globales sont nécessaires/utiles, mais celles-ci sont en effet peu nombreuses.
Votre problème concerne les espaces de noms. Lorsque vous importez Common dans second.py, GLOBAL_ONE
provient de cet espace de noms. Lorsque vous importez secondTest, il fait toujours référence à GLOBAL_ONE
depuis common.py.
Votre vrai problème, cependant, est avec la conception. Je ne peux pas penser à une seule raison logique bonne d'implémenter une variable globale de cette façon. Les variables globales sont une affaire délicate en Python car il n'existe pas de variable constante. Cependant, la convention est que lorsque vous voulez garder quelque chose de constant en Python, vous le nommez WITH_ALL_CAPS
. Ergo:
somevar = MY_GLOBAL_VAR # good!
MY_GLOBAL_VAR = somevar # What? You "can't" assign to a constant! Bad!
Il y a beaucoup de raisons qui font quelque chose comme ceci:
earth = 6e24
def badfunction():
global earth
earth += 1e5
print '%.2e' % earth
est terribles.
Bien sûr, si vous faites cela simplement pour comprendre les espaces de noms et l'appel global
, continuez.
Sinon, certaines des raisons que les variables globales sont une mauvaise chose ™ sont:
- pollution Namespace
- Intégration fonctionnelle - vous voulez que vos fonctions à compartimentés
- effets secondaires fonctionnels - ce se produit lorsque vous écrivez une fonction qui modifie la variable globale
balance
et que vous ou quelqu'un d'autre réutilise votre fonction et n'en tient pas compte? Si vous calculiez le solde du compte, tout d'un coup, vous en avez trop ou pas assez. Des bugs comme celui-ci sont difficiles à trouver.
Si vous avez une fonction qui a besoin d'une valeur, vous devez lui transmettre cette valeur en tant que paramètre, sauf si vous avez une raison valable. Une raison serait d'avoir un global de PI - en fonction de vos besoins de précision, vous voudrez peut-être 3.14
, ou vous pouvez le vouloir 3.14159265
... mais c'est un cas où un global a du sens. Il y a probablement seulement une poignée ou deux cas réels qui peuvent utiliser correctement les globals. L'un des cas sont des constantes dans la programmation de jeux. Il est plus facile d'importer pygame.locals et d'utiliser KP_UP que de se souvenir de la valeur entière répondant à cet événement. Ce sont exceptions à la règle.
Et (au moins dans pygame) ces constantes sont stockées dans un fichier séparé - juste pour les constantes. Tout module qui a besoin de ces constantes va importer ces constantes. Lorsque vous programmez, vous écrivez des fonctions pour décomposer votre problème en blocs gérables. De préférence une fonction devrait faire une chose, et n'ont pas d'effets secondaires. Cela signifie qu'une fonction telle que calculatetime() doit calculer l'heure. Il ne devrait probablement pas aller lire un fichier qui contient l'heure, et interdire qu'il devrait faire quelque chose comme écrire l'heure quelque part. Il peut retourner le temps, et prendre des paramètres si elle en a besoin - les deux sont des choses bonnes, acceptables pour les fonctions à faire. Les fonctions sont une sorte de contrat entre vous (le programmeur de la fonction) et n'importe qui (y compris vous) qui utilise la fonction. L'accès à et la modification des variables globales constituent une violation de ce contrat car la fonction peut modifier les données externes de manière non définie ou attendue. Lorsque j'utilise cette fonction calculatetime()
, je m'attends à ce qu'il calcule l'heure et la renvoie probablement, ne modifie pas le temps variable global qui répond à l'heure du module que je viens d'importer.
La modification des variables globales rompt le contrat et la distinction logique entre les actions que votre programme prend. Ils peuvent introduire des bogues dans votre programme. Ils rendent difficile la mise à niveau et la modification des fonctions. Lorsque vous utilisez en tant que variables au lieu globals de constante, death awaits you with sharp pointy teeth!
lecture sur les étendues et les espaces de noms en Python http://docs.python.org/ tutorial/classes.html # python-scopes-and-namespaces – jfs