2009-09-05 12 views
72

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 fichier __init__.py 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?Puis-je utiliser __init__.py pour définir des variables globales?

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

Répondre

120

Vous devriez être en mesure de les mettre en __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, mymodule import:

>>> from mypackage import mymodule 
my constant is 42 

encore, si vous avez constante s, il serait raisonnable (les meilleures pratiques, probablement) de les placer dans un module séparé (constants.py, config.py, ...) et ensuite, si vous les voulez dans l'espace de nom du paquet, importez-les.

mypackage/__init__.py:

from mypackage.constants import * 

Pourtant, cela ne comprend pas automatiquement les constantes dans les espaces de noms des modules de paquet. Chacun des modules du package devra toujours importer les constantes explicitement soit à partir de mypackage soit à partir de mypackage.constants.

+0

Oui, il est logique que vous deviez les importer. –

+9

Cela aurait dû être la réponse acceptée. Si vous travaillez avec Python 2.5 ou supérieur, vous pouvez également utiliser une importation relative explicite ainsi que décrite [ici] (http://docs.python.org/2/tutorial/modules.html#intra-package-references): 'partir de. import MY_CONSTANT' – ThatAintWorking

+0

Cette réponse est correcte et donne une solution directe plutôt qu'une solution de contournement. Merci de fournir ceci et cela devrait être la réponse acceptée. +1 – Hazok

30

Vous ne pouvez pas faire cela. Vous devrez importer explicitement vos constantes dans l'espace de noms de chaque module. La meilleure façon d'y parvenir est de définir vos constantes dans un module « config » et l'importer partout vous en avez besoin:

# mypackage/config.py 
MY_CONST = 17 

# mypackage/main.py 
from mypackage.config import * 
+0

Ouais, un fichier de configuration est ce que J'aimerais. Je pensais juste que __init__.py serait un bon endroit. Votre solution ressemble à la pratique standard. Est-ce? –

+0

Bon point. Je n'ai pas réalisé que la question était d'avoir les constantes _automatically_ placées dans l'espace de noms de tous les modules du paquet. –

+0

Mais à chaque fois qu'un script importe config.py, le code à l'intérieur est exécuté. Que recommandez-vous si le code dans config.py doit être exécuté une seule fois? Dites que je lis un fichier settings.json dans config.py et que je ne veux pas l'ouvrir() à chaque fois que j'importe config.py. – Augiwan

2

Vous pouvez définir des variables globales de n'importe où, mais c'est une très mauvaise idée. importez le module __builtin__ et modifiez ou ajoutez des attributs à ce module, et vous avez soudainement de nouvelles constantes ou fonctions intégrées. En fait, lorsque mon application installe gettext, j'obtiens la fonction _() dans tous mes modules, sans importer quoi que ce soit. Donc c'est possible, mais bien sûr seulement pour les projets de type Application, pas pour les paquets 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.

1

Je voulais juste ajouter que les constantes peuvent être employées en utilisant un fichier config.ini et analysées dans le script en utilisant la bibliothèque configparser . De cette façon, vous pourriez avoir des constantes pour plusieurs circonstances. Par exemple, si vous les aviez constantes de paramètres pour deux requêtes URL distinctes étiquette comme si:

mymodule/config.ini 
[request0] 
conn = '[email protected]' 
pass = 'admin' 
... 

[request1] 
conn = '[email protected]' 
pass = 'dinosaur' 
... 

Je trouve la documentation sur le site Python très utile.Je ne sais pas s'il y a des différences entre Python 2 et 3 voici donc les liens à la fois:

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

Questions connexes