Réponses:
Cela n'a rien à voir avec Python; les variables globales sont mauvaises dans n'importe quel langage de programmation.
Cependant, les constantes globales ne sont pas conceptuellement les mêmes que les variables globales ; les constantes globales sont parfaitement inoffensives. En Python, la distinction entre les deux est purement par convention: CONSTANTS_ARE_CAPITALIZED
et globals_are_not
.
La raison pour laquelle les variables globales sont mauvaises est qu'elles permettent aux fonctions d'avoir des effets secondaires cachés (non évidents, surprenants, difficiles à détecter, difficiles à diagnostiquer), conduisant à une augmentation de la complexité, conduisant potentiellement au code Spaghetti .
Cependant, une utilisation sensée de l'état global est acceptable (tout comme l'état local et la mutabilité) même dans la programmation fonctionnelle, que ce soit pour l'optimisation des algorithmes, la réduction de la complexité, la mise en cache et la mémorisation, ou le caractère pratique du portage de structures provenant d'une base de code principalement impérative.
Dans l'ensemble, votre question peut trouver une réponse de plusieurs manières, donc votre meilleur pari est simplement de google "pourquoi les variables globales sont-elles mauvaises". Quelques exemples:
Si vous voulez aller plus loin et découvrir pourquoi les effets secondaires sont liés, et bien d'autres choses éclairantes, vous devriez apprendre la programmation fonctionnelle:
Oui, en théorie , les globaux (et «l'état» en général) sont mauvais. En pratique, si vous regardez dans le répertoire des packages de votre python, vous constaterez que la plupart des modules commencent par un tas de déclarations globales. De toute évidence, les gens n'ont aucun problème avec eux.
Spécifiquement pour python, la visibilité des globaux est limitée à un module, donc il n'y a pas de "vrais" globaux qui affectent l'ensemble du programme - ce qui les rend moins dangereux. Autre point: il n'y en a pas const
, donc lorsque vous avez besoin d'une constante, vous devez utiliser un global.
Dans ma pratique, s'il m'arrive de modifier un global dans une fonction, je le déclare toujours avec global
, même si cela n'est techniquement pas nécessaire, comme dans:
cache = {}
def foo(args):
global cache
cache[args] = ...
Cela facilite la traçabilité des manipulations des globaux.
Une opinion personnelle sur le sujet est que l'utilisation de variables globales dans une logique de fonction signifie qu'un autre code peut modifier la logique et la sortie attendue de cette fonction, ce qui rendra le débogage très difficile (en particulier dans les grands projets) et rendra les tests plus difficiles. ainsi que.
De plus, si vous considérez que d'autres personnes lisent votre code (communauté open-source, collègues, etc.), elles auront du mal à essayer de comprendre où la variable globale est définie, où a été modifiée et à quoi s'attendre de cette variable globale par opposition à une fonction isolée que sa fonctionnalité peut être déterminée en lisant la définition de fonction elle-même.
Je crois qu'un code propre et (presque) sans bogue devrait avoir des fonctions aussi pures que possible (voir les fonctions pures ). Une fonction pure est celle qui a les conditions suivantes:
Le fait d'avoir des variables globales enfreint au moins l'un des éléments ci-dessus, sinon les deux, car un code externe peut probablement entraîner des résultats inattendus.
Une autre définition claire des fonctions pures: "Une fonction pure est une fonction qui prend toutes ses entrées comme arguments explicites et produit toutes ses sorties comme des résultats explicites ." [1] . Avoir des variables globales viole l'idée de fonctions pures puisqu'une entrée et peut-être l'une des sorties (la variable globale) n'est pas explicitement donnée ou retournée.
Plus loin, si l' on considère l' unité-test et le principe FIRST ( F tests ast, I des tests ndependent, R epeatable, S elfe validants et T Imely) violeront probablement les tests indépendants principe ( ce qui signifie que les tests ne dépendent sur l'un et l'autre).
Avoir une variable globale (pas toujours) mais dans la plupart des cas (du moins de ce que j'ai vu jusqu'à présent), c'est préparer et transmettre les résultats à d'autres fonctions. Cela viole également ce principe. Si la variable globale a été utilisée de cette manière (c'est-à-dire que la variable globale utilisée dans la fonction X doit d'abord être définie dans une fonction Y), cela signifie que pour tester l'unité de la fonction X, vous devez d'abord exécuter la fonction de test / exécution Y.
D'un autre côté et comme d'autres personnes l'ont déjà mentionné, si la variable globale est utilisée comme une variable «constante» peut être légèrement mieux puisque le langage ne supporte pas les constantes. Cependant, je préfère toujours travailler avec des classes et avoir les «constantes» en tant que membre de classe et ne pas utiliser du tout de variable globale. Si vous avez un code dont deux classes différentes ont besoin pour partager une variable globale, vous devez probablement refactoriser votre solution et rendre vos classes indépendantes.
Je ne pense pas que les globaux ne devraient pas être utilisés. Mais s'ils sont utilisés, les auteurs devraient considérer certains principes (ceux mentionnés ci-dessus peut-être et d'autres principes de génie logiciel et bonnes pratiques) pour un code plus propre et presque exempt de bogues.
Ils sont essentiels, l'écran en est un bon exemple. Cependant, dans un environnement multithread ou avec de nombreux développeurs impliqués, dans la pratique, la question se pose souvent: qui l'a (de manière erronée) définie ou effacée? En fonction de l'architecture, l'analyse peut être coûteuse et souvent requise. Bien que la lecture de la variable globale puisse être correcte, l'écriture doit être contrôlée, par exemple par un seul thread ou une classe threadsafe. Par conséquent, les vars mondiaux suscitent la peur des coûts de développement élevés possibles par les conséquences pour lesquelles ils sont considérés comme mauvais. Par conséquent, en général, il est recommandé de maintenir le nombre de variables mondiales bas.
eval
,import *
, concaténation de chaînes , variablesid
, les ombres d'attributs )