La __debug__
variable est pratique en partie parce qu'elle affecte chaque module. Si je veux créer une autre variable qui fonctionne de la même manière, comment le ferais-je?
La variable (soyons original et appelons-la «foo») n'a pas besoin d'être vraiment globale, en ce sens que si je change foo dans un module, elle est mise à jour dans les autres. Ce serait bien si je pouvais définir foo avant d'importer d'autres modules et qu'ils verraient la même valeur pour cela.
hasattr(__builtin__, "foo")
.Si vous avez besoin d'une variable globale inter-module, peut-être qu'une simple variable globale au niveau du module suffira.
a.py:
b.py:
c.py:
Tester:
Exemple du monde réel: global_settings.py de Django (bien que dans les applications Django, les paramètres soient utilisés en important l' objet
django.conf.settings
).la source
a.py
, contientmain()
? Est-ce que ça importe?if __name__=="__main__"
guard pour éviter d'exécuter du code inattendu lors de l'importation.id()
pour vérifier l'identité)Je crois qu'il existe de nombreuses circonstances dans lesquelles cela a du sens et cela simplifie la programmation d'avoir des globaux connus à travers plusieurs modules (étroitement couplés). Dans cet esprit, je voudrais développer un peu l'idée d'avoir un module de globals qui est importé par les modules qui ont besoin de les référencer.
Quand il n'y a qu'un seul module de ce type, je le nomme "g". Dans celui-ci, j'attribue des valeurs par défaut pour chaque variable que j'ai l'intention de traiter comme globale. Dans chaque module qui utilise l'un d'entre eux, je n'utilise pas "from g import var", car il en résulte uniquement une variable locale qui n'est initialisée à partir de g qu'au moment de l'importation. Je fais la plupart des références sous la forme g.var, et le "g." me rappelle constamment que j'ai affaire à une variable potentiellement accessible à d'autres modules.
Si la valeur d'une telle variable globale doit être utilisée fréquemment dans une fonction d'un module, alors cette fonction peut faire une copie locale: var = g.var. Cependant, il est important de comprendre que les affectations à var sont locales et que g.var global ne peut pas être mis à jour sans référencer explicitement g.var dans une affectation.
Notez que vous pouvez également avoir plusieurs modules globaux de ce type partagés par différents sous-ensembles de vos modules pour garder les choses un peu plus étroitement contrôlées. La raison pour laquelle j'utilise des noms courts pour mes modules globaux est d'éviter de trop encombrer le code avec leurs occurrences. Avec seulement un peu d'expérience, ils deviennent assez mnémotechniques avec seulement 1 ou 2 caractères.
Il est toujours possible de faire une assignation à, disons, gx quand x n'était pas déjà défini dans g, et un module différent peut alors accéder à gx Cependant, même si l'interpréteur le permet, cette approche n'est pas si transparente, et j'évite il. Il existe toujours la possibilité de créer accidentellement une nouvelle variable dans g à la suite d'une faute de frappe dans le nom de la variable pour une affectation. Parfois, un examen de dir (g) est utile pour découvrir les noms de surprise qui auraient pu survenir par un tel accident.
la source
Définissez un module (appelez-le "globalbaz") et définissez les variables à l'intérieur. Tous les modules utilisant ce "pseudoglobal" doivent importer le module "globalbaz", et s'y référer en utilisant "globalbaz.var_name"
Cela fonctionne quel que soit le lieu de la modification, vous pouvez modifier la variable avant ou après l'importation. Le module importé utilisera la dernière valeur. (J'ai testé cela dans un exemple de jouet)
Pour plus de précision, globalbaz.py ressemble à ceci:
la source
Vous pouvez transmettre les globaux d'un module à un autre:
Dans le module A:
Dans le module B:
la source
Les variables globales sont généralement une mauvaise idée, mais vous pouvez le faire en attribuant à
__builtins__
:De plus, les modules eux-mêmes sont des variables auxquelles vous pouvez accéder à partir de n'importe quel module. Donc, si vous définissez un module appelé
my_globals.py
:Ensuite, vous pouvez également l'utiliser de n'importe où:
Utiliser des modules plutôt que de les modifier
__builtins__
est généralement une manière plus propre de faire des globaux de ce genre.la source
__builtins__
est une particularité de CPython, vous ne devriez vraiment pas l'utiliser - meilleure utilisation__builtin__
(oubuiltins
en Python3) comme le montre la réponse acceptéeVous pouvez déjà le faire avec des variables au niveau du module. Les modules sont les mêmes quel que soit le module à partir duquel ils sont importés. Ainsi, vous pouvez faire de la variable une variable de niveau module dans n'importe quel module dans lequel il est judicieux de la placer, et y accéder ou lui affecter à partir d'autres modules. Il serait préférable d'appeler une fonction pour définir la valeur de la variable ou d'en faire une propriété d'un objet singleton. De cette façon, si vous finissez par avoir besoin d'exécuter du code lorsque la variable est modifiée, vous pouvez le faire sans casser l'interface externe de votre module.
Ce n'est généralement pas une excellente façon de faire les choses - l'utilisation de globaux l'est rarement - mais je pense que c'est la façon la plus propre de le faire.
la source
Je voulais poster une réponse qu'il y a un cas où la variable ne sera pas trouvée.
Les importations cycliques peuvent interrompre le comportement du module.
Par exemple:
first.py
second.py
main.py
Sur cet exemple, cela devrait être évident, mais dans une grande base de code, cela peut être vraiment déroutant.
la source
Cela ressemble à la modification de l'
__builtin__
espace de nom. Pour le faire:N'utilisez pas
__builtins__
directement (notez les "s" supplémentaires) - apparemment cela peut être un dictionnaire ou un module. Merci à ΤΖΩΤΖΙΟΥ de l'avoir signalé, vous en trouverez plus ici .Maintenant
foo
est disponible pour une utilisation partout.Je ne recommande pas de faire cela en général, mais l'utilisation de cela dépend du programmeur.
L'attribution doit être effectuée comme ci-dessus, le réglage
foo = 'some-other-value'
ne le définira que dans l'espace de noms actuel.la source
J'utilise ceci pour quelques fonctions primitives intégrées qui me manquaient vraiment. Un exemple est une fonction de recherche qui a la même sémantique d'utilisation que filtre, mappage, réduction.
Une fois que cela est exécuté (par exemple, en important près de votre point d'entrée), tous vos modules peuvent utiliser find () comme si, évidemment, il était intégré.
Remarque: vous pouvez le faire, bien sûr, avec un filtre et une autre ligne pour tester la longueur nulle, ou avec une réduction dans une sorte de ligne étrange, mais j'ai toujours pensé que c'était bizarre.
la source
Je pourrais obtenir des variables modifiables (ou mutables ) inter-modules en utilisant un dictionnaire:
Lors du lancement
test_wait_app_up_fail
, la durée réelle du timeout est de 3 secondes.la source
Je me suis demandé s'il serait possible d'éviter certains des inconvénients liés à l'utilisation de variables globales (voir par exemple http://wiki.c2.com/?GlobalVariablesAreBad ) en utilisant un espace de noms de classe plutôt qu'un espace de noms global / module pour passer des valeurs de variables . Le code suivant indique que les deux méthodes sont essentiellement identiques. Il y a un léger avantage à utiliser les espaces de noms de classe comme expliqué ci-dessous.
Les fragments de code suivants montrent également que des attributs ou des variables peuvent être créés et supprimés dynamiquement dans les espaces de noms globaux / module et les espaces de noms de classe.
wall.py
J'appelle ce module «mur» car il est utilisé pour rebondir des variables sur. Il agira comme un espace pour définir temporairement les variables globales et les attributs à l'échelle de la classe de la classe vide 'router'.
source.py
Ce module importe le mur et définit une fonction unique
sourcefn
qui définit un message et l'émet par deux mécanismes différents, l'un via les globaux et l'autre via la fonction routeur. Notez que les variableswall.msg
etwall.router.message
sont définies ici pour la première fois dans leurs espaces de noms respectifs.dest.py
Ce module définit une fonction
destfn
qui utilise les deux mécanismes différents pour recevoir les messages émis par la source. Cela permet la possibilité que la variable «msg» n'existe pas.destfn
supprime également les variables une fois qu'elles ont été affichées.main.py
Ce module appelle les fonctions précédemment définies dans l'ordre. Après le premier appel aux
dest.destfn
variableswall.msg
etwall.router.msg
n'existent plus.La sortie du programme est:
global: Bonjour tout le monde!
routeur: Bonjour tout le monde!
global: pas de
routeur de message : pas de message
Les fragments de code ci-dessus montrent que les mécanismes de variable module / global et classe / classe sont essentiellement identiques.
Si beaucoup de variables doivent être partagées, la pollution de l'espace de noms peut être gérée soit en utilisant plusieurs modules de type mur, par exemple wall1, wall2 etc., soit en définissant plusieurs classes de type routeur dans un seul fichier. Ce dernier est légèrement plus ordonné, donc représente peut-être un avantage marginal pour l'utilisation du mécanisme de variable de classe.
la source