web-dev-qa-db-fra.com

Puis-je utiliser __init__.py pour définir des variables globales?

Je veux définir une constante qui devrait être disponible dans tous les sous-modules d'un paquet. J'ai pensé que le meilleur endroit serait dans le __init__.py fichier du paquet racine. Mais je ne sais pas comment faire ça. Supposons que j'ai quelques sous-paquets et chacun avec plusieurs modules. Comment puis-je accéder à cette variable à partir de ces modules?

Bien sûr, si cela est totalement faux et qu'il existe une meilleure alternative, j'aimerais bien le savoir.

107
Andrei Vajna II

Vous devriez pouvoir les mettre dans __init__.py. Ceci est fait tout le temps.

mypackage/__init__.py:

MY_CONSTANT = 42

mypackage/mymodule.py:

from mypackage import MY_CONSTANT
print "my constant is", MY_CONSTANT

Ensuite, importez mymodule:

>>> from mypackage import mymodule
my constant is 42

Néanmoins, si vous avez des constantes, il serait raisonnable (meilleures pratiques, probablement) de les placer dans un module séparé (constants.py, config.py, ...) et si vous les voulez dans l’espace de noms du paquet, importez-les. leur.

mypackage/__init__.py:

from mypackage.constants import *

Néanmoins, cela n'inclut pas automatiquement les constantes dans les espaces de noms des modules du package. Chacun des modules du paquet devra toujours importer des constantes explicitement de mypackage ou de mypackage.constants.

172
Jason R. Coombs

Tu ne peux pas faire ça. Vous devrez importer explicitement vos constantes dans l'espace de noms de chaque module. Le meilleur moyen d'y parvenir est de définir vos constantes dans un module "config" et de les importer où vous le souhaitez:

# mypackage/config.py
MY_CONST = 17

# mypackage/main.py
from mypackage.config import *
30
Ferdinand Beyer

Vous pouvez définir des variables globales de n’importe où, mais c’est une très mauvaise idée. importer le __builtin__ module et modifiez ou ajoutez des attributs à ces modules, et tout à coup vous avez de nouvelles constantes ou fonctions intégrées. En fait, lorsque mon application installe gettext, j’obtiens la fonction _ () dans tous mes modules, sans rien importer. Cela est donc possible, mais bien sûr uniquement pour les projets de type Application, pas pour les packages ou modules réutilisables.

Et je suppose que personne ne recommanderait cette pratique de toute façon. Quel est le problème avec un espace de noms? Cette application a le module de version, de sorte que j'ai des variables "globales" disponibles comme version.VERSION, version.PACKAGE_NAME etc.

2
u0b34a0f6ae

Je voulais juste ajouter que les constantes peuvent être utilisées à l'aide d'un fichier config.ini et analysées dans le script à l'aide de la bibliothèque configparser. De cette façon, vous pouvez avoir des constantes pour plusieurs circonstances. Par exemple, si vous aviez des constantes de paramètre pour deux demandes d'URL distinctes, étiquetez-les comme suit:

mymodule/config.ini
[request0]
conn = 'admin@localhost'
pass = 'admin'
...

[request1]
conn = 'barney@localhost'
pass = 'dinosaur'
...

J'ai trouvé la documentation sur le site Web Python très utile. Je ne sais pas s'il existe des différences entre Python 2 et 3, voici donc les liens entre les deux :

Pour Python 3: https://docs.python.org/3/library/configparser.html#module-configparser)

Pour Python 2: https://docs.python.org/2/library/configparser.html#module-configparser)

1
Dan Temkin