Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Définir des variables globales pour tout un projet

+3 votes

Dans mon module principal j'ai plusieurs sous-modules et même des codes qui tournent en stand-alone. Ce module principal sert de template pour plusieurs projets, et plutôt que de devoir modifier à chaque fois les chemins qui servent à pointer vers tel ou tel code j'aimerais pouvoir mettre en place des variables globales.
Seulement voilà, je n'ai pas un seul point d'entrée mais une multitude (chaque code en stand-alone utilise des sous-modules mais se démerde tout seul niveau interface).
Pour le moment j'ai créé un code include.py qui déclare des variables globales à partir d'un dictionnaire (donc je n'ai plus qu'à le modifier LUI en fonction du projet et non plus toutes les occurrences de tous les chemins):

# include.py
global_dict = {'my_var1':1, 'my_var2':2,'my_varice':'is'}

import __main__ as namespace

# Add variables to namespace
for variable,value in global_dict.items():  
    setattr(namespace, variable, value)

mais il faut tout de même que j'importe ce code dans tous les init de tous les modules qui vont avoir besoin de mes variables.

Je me demande donc: y a-t-il un moyen pour faire sauter cet import? pour faire en sorte que tout ce qui se range dans un projet donné ait accès aux variables globales, et pas que j'aie à les redéclarer pour le namespace en cours à chaque fois?

Edit:
En fait ce que je voudrais c'est que tous les modules situés dans un projet défini aient accès à des variables "de base" (des chemins, pour être exact). Et ce quel que soit le point d'entrée (tant qu'il est dans ce projet).

demandé 16-Jun-2016 par furankun (1,416 points)
edité 22-Jun-2016 par furankun

Des variables d'environnements? Un fichier .ini?

Même chose pour moi, les variables d'environnement ou un fichier ini. Il faut éviter les variables globales. Si tu en as besoin c'est que l'architecture est mauvaise.

J'ai du mal à voir la différence en terme de fonctionnalité entre ce que je propose et l'utilisation d'un fichier ini (dont les variables devront être importées à chaque fois, de la même façon. Sauf à utiliser... des variables globales!).
Je suis en train de regarder pour modifier l'architecture mais c'est pas gagné.

5 Réponses

+1 vote

Utiliser des fichiers de conf avec un boiler plate ?
Sinon, j'utilise l'application appconf dans django pour surcharger les settings, tu peux peut-être jeter un œil au code proposé... très court !

répondu 16-Jun-2016 par frague (484 points)
+2 votes

Si j'ai bien compris, tu veux que ton code soit importé, sans faire de import ?

Je n'ai pas de preuve du contraire, mais il ne me semble pas que Python permette d'injecter du code au début du lancement d'un programme (à part en recompilant CPython).
Sinon, on n'aurait plus besoin de taper "import os/sys" à chaque fois.

Par contre, en faisant un package installable via pip, en changeant à la main le pythonpath, où en mettant ton module dans les dossiers accédés par pythonpath, tu pourrais l'importer avec un "import include".

répondu 17-Jun-2016 par anonyme

En fait ce que je voudrais c'est que tous les modules situés dans un projet défini aient accès à des variables "de base" (des chemins, pour être exact). Et ce quel que soit le point d'entrée (tant qu'il est dans ce projet).

Pour partager une variables, je crois qu'on ne peut utiliser que les imports (from globalfile import globaldict) (cpython ne recharge pas 2 fois le même fichier, donc ça sera la même variable accessible partout. J'avais fait ça une fois avec un acteur, en utilisant la concurrence).

En gérant bien l'organisation du projet (c'est à dire en mettant tous les points de départs en haut), il n'y a pas besoin de manipuler le pythonpath.

+3 votes

Ce que tu fais aujourd'hui me paraît la bonne solution : 'import include' là où tu en as besoin.

Éventuellement, tu pourrais utiliser la variable __all__ du module include pour pouvoir faire 'from include import *' en gardant le contrôle des noms effectivement importés.

En reprenant ton exemple de include.py, ça pourrait donner :

# include.py
global_dict = {'my_var1':1, 'my_var2':2,'my_varice':'is'}

__all__ = list(global_dict)  # <-- 'from include import *'
                             #     n'importe que 'my_var', 'my_var2' et 'my_varice'

import __main__ as namespace

# Add variables to namespace
for variable,value in global_dict.items():  
    setattr(namespace, variable, value)
répondu 23-Jun-2016 par bubulle (2,066 points)
+3 votes

Créer un objet de configuration, et importe toujours cet objet. Fait en sorte que l'objet lise la config depuis la ligne de commande, un fichier de conf, une variable d'env, etc.

répondu 23-Jun-2016 par Sam (4,974 points)
+2 votes

tu peux aussi mettre un import dans un fichier pth à la racine de ton installation python, ça va exécuter le contenu du fichier importé pour tout lancement de python. Pas forcement le mieux, mais un comportement intéressant.
http://bob.ippoli.to/archives/2005/02/06/using-pth-files-for-python-development/

répondu 25-Jul-2016 par cocolauz (116 points)
...