web-dev-qa-db-fra.com

Vous utilisez des variables globales entre fichiers?

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

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

# ../myproject/main.py

# Define global myList
global myList
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

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

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
    globals()["myList"].append("hey")

n autre moyen que j'ai essayé, mais n'a pas fonctionné non plus

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

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

# ../myproject/subfile.py

# Import globfile
import globfile

# Save "hey" into myList
def stuff():
    globfile.myList.append("hey")

Mais encore une fois, cela n'a pas fonctionné. Comment dois-je implémenter cela? Je comprends que cela ne peut pas fonctionner comme ça, quand les deux fichiers ne se connaissent pas vraiment (et que le sous-fichier ne sait pas le fichier principal), mais je ne vois pas comment le faire sans utiliser io write ou pickle, qui Je ne veux pas faire.

158
user1632861

Le problème est que vous avez défini myList à partir de main.py, mais subfile.py doit l’utiliser. Voici un moyen propre de résoudre ce problème: déplacez tous les globals dans un fichier, j'appelle ce fichier settings.py. Ce fichier est responsable de la définition des globales et de leur initialisation:

# settings.py

def init():
    global myList
    myList = []

Ensuite, votre subfile peut importer des éléments globaux:

# subfile.py

import settings

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

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

# main.py

import settings
import subfile

settings.init()          # Call only once
subfile.stuff()         # Do stuff with global var
print settings.myList[0] # Check the result

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

264
Hai Vu

Voir le document de Python sur partage des variables globales entre modules :

Le moyen canonique de partager des informations entre les modules d'un même programme consiste à créer un module spécial (souvent appelé config ou cfg).

config.py:

x = 0   # Default value of the 'x' configuration setting

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

main.py:

import config
print config.x

ou

from config import x
print x

Cela vous permettra également de définir une telle variable de manière dynamique :

import config
config.x = my_function

En général, n’utilisez pas à partir de modulename import * . Cela encombrerait l’espace de noms de l’importateur et empêcherait beaucoup les linters de détecter des noms indéfinis.

68
Ogaga Uzoh

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

Une variable globale est en réalité définie dans le __dict__ d'un module et est accessible de l'extérieur du module en tant qu'attribut de module.

Donc, dans votre exemple:

# ../myproject/main.py

# Define global myList
# global myList  - there is no "global" declaration at module level. Just inside
# function and methods
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

Et:

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
     # You have to make the module main available for the 
     # code here.
     # Placing the import inside the function body will
     # usually avoid import cycles - 
     # unless you happen to call this function from 
     # either main or subfile's body (i.e. not from inside a function or method)
     import main
     main.mylist.append("hey")
20
jsbueno

Utiliser from your_file import * devrait résoudre vos problèmes. Il définit tout pour qu'il 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!"
12
IT Ninja

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

Si vous utilisez le global dans un autre module et que vous souhaitez définir le global de manière dynamique, importez 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("1st")     # global init before used in other imported modules
                         # Or else they will be undefined

import subfile    
subfile.print()          # global usage
8
lastboy

Votre deuxième tentative fonctionnera parfaitement et constitue en réalité un très bon moyen de gérer les noms de variables que vous souhaitez disposer de manière globale. Mais vous avez une erreur de nom dans la dernière ligne. Voici comment cela devrait être:

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

Voir la dernière ligne? myList est un attr de globfile, pas de sous-fichier. Cela fonctionnera comme vous voulez.

Mike

4
MikeHunter