333 votes

Utilisation de variables globales entre les fichiers ?

Je suis un peu confus sur le fonctionnement des variables globales. J'ai un grand projet, avec environ 50 fichiers, et j'ai besoin de définir des variables globales pour tous ces fichiers.

Ce que j'ai fait était de les définir dans le fichier main.py de mon projet, comme suit :

# ../monprojet/main.py

# Définir global myList
global myList
myList = []

# Imports
import subfile

# Faire quelque chose
subfile.stuff()
print(myList[0])

J'essaie d'utiliser myList dans subfile.py, comme suit

# ../monprojet/subfile.py

# Enregistrer "hey" dans myList
def stuff():
    globals()["myList"].append("hey")

Une autre façon que j'ai essayée, mais qui n'a pas fonctionné non plus

# ../monprojet/main.py

# Import globfile    
import globfile

# Enregistrer myList dans globfile
globfile.myList = []

# Import subfile
import subfile

# Faire quelque chose
subfile.stuff()
print(globfile.myList[0])

Et à l'intérieur de subfile.py j'avais ceci :

# ../monprojet/subfile.py

# Import globfile
import globfile

# Enregistrer "hey" dans myList
def stuff():
    globfile.myList.append("hey")

Mais encore une fois, ça n'a pas fonctionné. Comment devrais-je implémenter cela ? Je comprends que cela ne peut pas fonctionner comme ça, lorsque les deux fichiers ne se connaissent pas vraiment (enfin subfile ne connaît pas main), mais je ne vois pas comment le faire, sans utiliser l'écriture io ou pickle, ce que je ne veux pas faire.

479voto

Hai Vu Points 10359

Le problème est que vous avez défini myList depuis main.py, mais subfile.py a besoin de l'utiliser. Voici une façon propre de résoudre ce problème : déplacez toutes les variables globales dans un fichier, que j'appelle settings.py. Ce fichier est responsable de la définition des variables globales et de leur initialisation :

# settings.py

def init():
    global myList
    myList = []

Ensuite, votre subfile peut importer les variables globales :

# subfile.py

import settings

def stuff():
    settings.myList.append('salut')

Notez que subfile n'appelle pas init()— cette tâche revient à main.py :

# main.py

import settings
import subfile

settings.init()          # Appeler une seule fois
subfile.stuff()         # Faire quelque chose avec la variable globale
print settings.myList[0] # Vérifier le résultat

De cette façon, vous atteignez votre objectif tout en évitant d'initialiser les variables globales plus d'une fois.

196voto

Ogaga Uzoh Points 1454

Consultez le document Python sur le partage de variables globales entre modules:

La manière canonique de partager des informations entre modules au sein d'un même programme est de créer un module spécial (souvent appelé config ou cfg).

config.py:

x = 0   # Valeur par défaut du paramètre de configuration 'x'

Importez le module config dans tous les modules de votre application ; le module devient alors disponible sous forme de nom global.

main.py:

import config
print (config.x)

En général, n'utilisez pas from nommodule import *. Ceci encombre l'espace de noms de l'importateur et rend la détection de noms indéfinis beaucoup plus difficile pour les linters.

24voto

jsbueno Points 22212

Vous pouvez penser aux variables globales Python comme des variables "module" - et en tant que telles, elles sont beaucoup plus utiles que les "variables globales" traditionnelles de C.

Une variable globale est en fait définie dans le __dict__ d'un module et peut être accessible depuis l'extérieur de ce module en tant qu'attribut du module.

Donc, dans votre exemple:

# ../myproject/main.py

# Définir global myList
# global myList  - il n'y a pas de déclaration "global" au niveau du module. Juste à l'intérieur
# de fonctions et méthodes
myList = []

# Imports
import subfile

# Faire quelque chose
subfile.stuff()
print(myList[0])

Et:

# ../myproject/subfile.py

# Enregistrer "hey" dans myList
def stuff():
     # Vous devez rendre le module main disponible pour le 
     # code ici.
     # Placer l'import à l'intérieur du corps de la fonction
     # évite généralement les boucles d'import - 
     # sauf si vous appelez cette fonction à partir 
     # du corps de main ou de subfile (c'est-à-dire pas à l'intérieur d'une fonction ou d'une méthode)
     import main
     main.mylist.append("hey")

12voto

IT Ninja Points 2257

Utiliser from votre_fichier import * devrait résoudre vos problèmes. Cela définit tout de manière à ce que ce soit globalement disponible (à l'exception des variables locales dans les importations bien sûr).

par exemple:

##test.py:

from pytest import *

print hello_world

et:

##pytest.py

hello_world="hello world!"

10voto

arik Points 256

La réponse de Hai Vu fonctionne très bien, juste un commentaire :

Dans le cas où vous utilisez le global dans un autre module et que vous souhaitez définir le global de manière dynamique, faites attention à importer les autres modules après avoir défini les variables globales, par exemple :

# settings.py
def init(arg):
    global myList
    myList = []
    myList.append(arg)

# subfile.py
import settings

def print():
    settings.myList[0]

# main.py
import settings
settings.init("1er")     # initialisation globale avant utilisation dans d'autres modules importés
                         # Sinon, ils seront indéfinis

import subfile    
subfile.print()          # utilisation globale

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X