web-dev-qa-db-fra.com

Définition de listes en tant que variables globales dans Python

J'utilise une liste sur laquelle certaines fonctions fonctionnent dans mon programme. Il s'agit en fait d'une liste partagée et toutes mes fonctions peuvent la modifier. Faut-il vraiment le définir comme "global" dans toutes les fonctions?

Je veux dire mettre le mot-clé global derrière lui dans chaque fonction qui l'utilise, ou le définir en dehors de toutes les fonctions est suffisant sans utiliser le mot global derrière sa définition?

13
Hossein

Lorsque vous affectez une variable (x = ...), vous créez une variable dans la portée actuelle (par exemple locale à la fonction actuelle). S'il arrive d'occulter une variable sur une portée externe (par exemple globale), tant pis - Python ne s'en soucie pas (et c'est une bonne chose). Vous ne pouvez donc pas faire cela:

x = 0
def f():
    x = 1
f()
print x #=>0

et attendez 1. Au lieu de cela, vous devez déclarer que vous avez l'intention d'utiliser le global x:

x = 0
def f():
    global x
    x = 1
f()
print x #=>1

Mais notez que l'affectation d'une variable est très différente des appels de méthode. Vous pouvez toujours appeler des méthodes sur n'importe quoi dans la portée - par exemple sur les variables qui proviennent d'une portée externe (par exemple la portée globale) car rien de local ne les masque.

Aussi très important: Affectation des membres (x.name = ...), affectation d'élément (collection[key] = ...), affectation de tranche (sliceable[start:end] = ...) et probablement plus sont tous des appels de méthode! Et par conséquent, vous n'avez pas besoin de global pour modifier les membres d'un global ou l'appeler méthodes (même lorsqu'ils mutent l'objet).

27
user395760

Oui, vous devez utiliser global foo si vous allez y écrire.

foo = []

def bar():
    global foo
    ...
    foo = [1]
5
Taylor Leese

Non, vous pouvez spécifier la liste comme argument de mot clé pour votre fonction.

alist = []
def fn(alist=alist):
    alist.append(1)
fn()
print alist    # [1]

Je dirais cependant que c'est une mauvaise pratique. Un peu trop hackish. Si vous avez vraiment besoin d'utiliser une structure de données de type singleton disponible à l'échelle mondiale, j'utiliserais l'approche des variables de niveau module, c'est-à-dire que vous mettriez 'alist' dans un module, puis dans vos autres modules, importer cette variable:

Dans le fichier foomodule.py:

alist = []

Dans le fichier barmodule.py:

import foomodule
def fn():
    foomodule.alist.append(1)
print foomodule.alist    # [1]
1
XORcist