web-dev-qa-db-fra.com

Utilisation du mot clé "global" en Python

D'après ce que je comprends de la lecture de la documentation, Python dispose d'un espace de noms séparé pour les fonctions. Si je souhaite utiliser une variable globale dans cette fonction, je dois utiliser global.

J'utilise Python 2.7 et j'ai essayé ce petit test

>>> sub = ['0', '0', '0', '0']
>>> def getJoin():
...     return '.'.join(sub)
...
>>> getJoin()
'0.0.0.0'

Il semble que les choses fonctionnent bien même sans global. J'ai pu accéder à la variable globale sans aucun problème.

Est-ce que je manque quelque chose? En outre, voici la documentation de Python:

Noms répertoriés dans une déclaration globale ne doit pas être défini comme formel paramètres ou dans un contrôle de boucle for cible, définition de classe, fonction définition, ou déclaration d'importation.

Bien que les paramètres formels et la définition de classe aient un sens pour moi, je ne suis pas en mesure de comprendre la restriction relative à la définition de cible et de fonction de contrôle de boucle.

256
nik

Le mot clé global n'est utile que pour modifier ou créer des variables globales dans un contexte local, bien que la création de variables globales soit rarement considérée comme une bonne solution.

def bob():
    me = "locally defined"    # Defined only in local context
    print me

bob()
print me     # Asking for a global variable

Ce qui précède vous donnera:

locally defined
Traceback (most recent call last):
  File "file.py", line 9, in <module>
    print me
NameError: name 'me' is not defined

Tandis que si vous utilisez l'instruction global, la variable deviendra disponible "en dehors" de la portée de la fonction, devenant ainsi une variable globale.

def bob():
    global me
    me = "locally defined"   # Defined locally but declared as global
    print me

bob()
print me     # Asking for a global variable

Donc, le code ci-dessus vous donnera:

locally defined
locally defined

De plus, en raison de la nature de python, vous pouvez également utiliser global pour déclarer des fonctions, des classes ou d’autres objets dans un contexte local. Bien que je le déconseille car cela provoque des cauchemars si quelque chose ne va pas ou nécessite un débogage.

337
unode

Bien que vous puissiez accéder aux variables globales sans le mot clé global, vous devez utiliser le mot clé global pour les modifier. Par exemple:

foo = 1
def test():
    foo = 2 # new local foo

def blub():
    global foo
    foo = 3 # changes the value of the global foo

Dans votre cas, vous accédez simplement à la liste sub.

196
Ivo Wetzel

C'est la différence entre accéder au nom et binding it dans une étendue.

Si vous recherchez simplement une variable pour lire sa valeur, vous avez accès à la portée globale et locale.

Toutefois, si vous affectez à une variable dont le nom ne se trouve pas dans l'étendue locale, vous êtes binding et entrez ce nom dans cette étendue (et si ce nom existe également sous forme globale, vous le masquerez). 

Si vous voulez pouvoir affecter le nom global, vous devez indiquer à l'analyseur d'utiliser le nom global plutôt que de lier un nouveau nom local, comme le fait le mot-clé 'global'.

La liaison n'importe où dans un bloc entraîne la liaison du nom partout dans ce bloc, ce qui peut avoir des conséquences plutôt étranges (par exemple, UnboundLocalError, apparaissant soudainement dans un code fonctionnant auparavant).

>>> a = 1
>>> def p():
    print(a) # accessing global scope, no binding going on
>>> def q():
    a = 3 # binding a name in local scope - hiding global
    print(a)
>>> def r():
    print(a) # fail - a is bound to local scope, but not assigned yet
    a = 4
>>> p()
1
>>> q()
3
>>> r()
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    r()
  File "<pyshell#32>", line 2, in r
    print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>> 
66
pycruft

Les autres réponses répondent à votre question. Une autre chose importante à savoir sur les noms en Python est qu'ils sont soit locaux, soit globaux pour chaque périmètre.

Considérez ceci, par exemple:

value = 42

def doit():
    print value
    value = 0

doit()
print value

Vous pouvez probablement deviner que l'instruction value = 0 sera assignée à une variable locale et n'affectera pas la valeur de la même variable déclarée en dehors de la fonction doit(). Vous serez peut-être plus surpris de découvrir que le code ci-dessus ne fonctionnera pas. L'instruction print value à l'intérieur de la fonction produit un UnboundLocalError.

La raison en est que Python a remarqué que, ailleurs dans la fonction, vous attribuez le nom value et que value n'est nulle part déclaré global. Cela en fait une variable locale. Mais lorsque vous essayez de l’imprimer, le nom local n’a pas encore été défini. Dans ce cas, Python ne recule pas à rechercher le nom en tant que variable globale, comme le font d’autres langages. Pour l'essentiel, vous ne pouvez pas accéder à une variable globale si vous avez défini une variable locale du même nom n'importe où dans la fonction.

47
kindall

L'accès à un nom et l'attribution d'un nom sont différents. Dans votre cas, vous accédez simplement à un nom.

Si vous affectez une variable dans une fonction, cette variable est supposée locale, sauf si vous la déclarez globale. En l'absence de cela, il est supposé être global.

>>> x = 1         # global 
>>> def foo():
        print x       # accessing it, it is global

>>> foo()
1
>>> def foo():   
        x = 2        # local x
        print x 

>>> x            # global x
1
>>> foo()        # prints local x
2
12
user225312
  • Vous pouvez accéder aux mots-clés globaux sans le mot-clé global
  • Pour pouvoir les modifier, vous devez indiquer explicitement que le mot clé est global. Sinon, le mot clé sera déclaré dans la portée locale.

Exemple:

words = [...] 

def contains (Word): 
    global words             # <- not really needed
    return (Word in words) 

def add (Word): 
    global words             # must specify that we're working with a global keyword
    if Word not in words: 
        words += [Word]
6
martynas

Toute variable déclarée en dehors d'une fonction est supposée être globale. Ce n'est qu'en les déclarant à l'intérieur des fonctions (sauf les constructeurs) que vous devez spécifier que la variable est globale.

2
Jesus Ramos

je vais vous donner un exemple simple: pensez à ce code: 

myVar = 0 
print (myVar )      # 01 line: returns 0

def func():
    myVar  = "def"
    print (myVar )

func()              # 02 line: returns def
print (myVar )      # 03 line: returns 0

comme vous pouvez le constater, la dernière ligne de code renvoie 0, car à l'intérieur de la fonction, la variable myVar n'a pas été réaffectée, elle vient d'être modifiée et ne change que uniquement lorsque la fonction est appelée sans affecter la variable principale myVar , car elle est définie dans la fonction our (signifie que c'est une variable locale), mais avec l'utilisation du mot clé global en tant que tel:

 myVar  = 0 
print (myVar )       # 01 Line : returns 0

def func():
    global myVar 
    myVar  = "def"
    print (myVar )

func()               # 02 Line : returns def
print (myVar )       # 03 Line : returns def

en ordonnant à python que cette variable dans def ne soit pas locale, nous utilisons la variable globale nommée myVar pour la changer.

0
a_m_dev

Global rend la variable "Global"

def out():
    global x
    x = 1
    print(x)
    return


out()

print (x)

Cela fait que "x" se comporte comme une variable normale en dehors de la fonction. Si vous supprimiez le global, cela donnerait une erreur car il ne peut pas imprimer une variable dans une fonction.

def out():
     # Taking out the global will give you an error since the variable x is no longer 'global' or in other words: accessible for other commands
    x = 1
    print(x)
    return


out()

print (x)
0
Michael

Cela signifie que vous ne devriez pas faire ce qui suit:

x = 1

def myfunc():
  global x

  # formal parameter
  def localfunction(x):
    return x+1

  # import statement
  import os.path as x

  # for loop control target
  for x in range(10):
    print x

  # class definition
  class x(object):
    def __init__(self):
      pass

  #function definition
  def x():
    print "I'm bad"
0
ikostia

Ceci est bien expliqué dans la Python FAQ

Quelles sont les règles pour les variables locales et globales en Python?

En Python, les variables qui ne sont référencées que dans une fonction sont implicitement globales. Si une valeur est affectée à une variable n'importe où dans le corps de la fonction, elle est supposée être locale, sauf si explicitement déclarée comme globale.

Bien qu’un peu surprenant au début, un instant de considération l’explique. D'une part, exiger global pour les variables affectées constitue un obstacle contre les effets secondaires non désirés. Par contre, si global était requis pour toutes les références globales, vous utiliseriez toujours global. Vous devez déclarer comme global chaque référence à une fonction intégrée ou à un composant d’un module importé. Cet encombrement irait à l'encontre de l'utilité de la déclaration global pour identifier les effets secondaires.

https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

0
user7610