Comprendre les Variables Globales et Nonlocales en Python

Introduction

Lorsque vous écrivez du code Python, les variables peuvent exister dans différentes portées (scopes) — par exemple, à l’intérieur d’une fonction, d’une fonction imbriquée, ou bien au sommet de votre script (portée globale).

Comprendre comment définir et modifier des variables globales et nonlocales est essentiel pour écrire un code propre, prévisible et facile à maintenir.

Variables Globales

Une variable globale est définie en dehors de toute fonction ou classe, et peut être utilisée partout dans le fichier.

Par défaut, Python considère que les variables assignées à l’intérieur d’une fonction sont locales à cette fonction.
Si vous souhaitez modifier une variable globale dans une fonction, vous devez la déclarer à l’aide du mot-clé global.

Exemple : Définir et utiliser une variable globale

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Variable globale
counter = 0

def increment():
    global counter  # Déclare que nous voulons utiliser la variable globale 'counter'
    counter += 1
    print("À l’intérieur de la fonction :", counter)

increment()
increment()

print("À l’extérieur de la fonction :", counter)

Sortie :

1
2
3
À lintérieur de la fonction : 1
À lintérieur de la fonction : 2
À lextérieur de la fonction : 2

Sans global, vous obtiendrez une erreur

Si vous essayez de modifier une variable globale à l’intérieur d’une fonction sans le mot-clé global :

1
2
3
4
5
6
7
counter = 0

def increment():
    counter += 1  # UnboundLocalError
    print(counter)

increment()

Erreur :

1
UnboundLocalError: local variable 'counter' referenced before assignment

Python suppose que counter est une variable locale, et signale une erreur car aucune valeur ne lui a été attribuée dans la portée locale.

Variables Nonlocales

Une variable nonlocale permet de modifier une variable dans la portée englobante la plus proche (mais pas dans la portée globale).

Ce mécanisme est principalement utilisé dans les fonctions imbriquées — c’est-à-dire des fonctions définies à l’intérieur d’une autre fonction.

Exemple : Utiliser une variable nonlocale

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def outer():
    x = 10

    def inner():
        nonlocal x   # Accède à la variable 'x' définie dans 'outer'
        x += 5
        print("À l’intérieur de inner :", x)

    inner()
    print("À l’intérieur de outer :", x)

outer()

Sortie :

1
2
À lintérieur de inner : 15
À lintérieur de outer : 15

Ici :

  • x n’est pas globale, mais appartient à la fonction outer().
  • En utilisant nonlocal, inner() modifie x depuis la portée englobante.

Sans nonlocal, la modification échoue

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def outer():
    x = 10

    def inner():
        x += 5  # UnboundLocalError
        print(x)

    inner()

outer()

Vous obtiendrez :

1
UnboundLocalError: local variable 'x' referenced before assignment

Python pense que vous essayez de créer une nouvelle variable locale x à l’intérieur de inner().

Tableau Comparatif

Fonctionnalité Portée affectée Utilisée dans Cas d’utilisation typique
global Niveau du module Toute fonction Modifier une variable globale
nonlocal Fonction englobante Fonctions imbriquées Modifier une variable englobante non globale

Résumé

  • Les variables définies dans une fonction sont locales par défaut.
  • Utilisez global pour modifier une variable globale à l’intérieur d’une fonction.
  • Utilisez nonlocal pour modifier une variable dans une portée englobante (non globale).
  • Évitez d’abuser du mot-clé global — préférez retourner des valeurs ou utiliser des classes pour un code plus propre.

Exemple

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
x = 100

def outer():
    x = 50
    def inner():
        global x
        x += 10
        print("Inner :", x)
    inner()
    print("Outer :", x)

outer()
print("Global :", x)

Sortie :

1
2
3
Inner : 110
Outer : 50
Global : 110

Quand Définir une Variable Globale en Dehors d’une Fonction en Python

Quand les Variables Globales Sont Utiles

Une variable globale définie en dehors de toute fonction est utile lorsque :

Vous avez besoin d’un état ou de constantes partagées

Par exemple, une valeur de configuration, un chemin, ou une constante qui ne change pas pendant l’exécution :

1
2
BASE_URL = "https://api.nasa.gov"
VERSION = 1.0

Ce sont des variables globales — et les fonctions peuvent les lire directement.

Vous voulez que plusieurs fonctions accèdent à la même variable

1
2
3
4
5
6
7
8
9
counter = 0

def increment():
   global counter
   counter += 1

def reset():
   global counter
   counter = 0

Ici, les deux fonctions utilisent la même variable counter définie globalement.

Vous écrivez de petits scripts ou prototypes

Pour des programmes simples et courts, les variables globales peuvent simplifier le code.

Quand Éviter les Variables Globales

Les variables globales deviennent un problème lorsque :

  • Votre code devient volumineux et plusieurs fonctions les modifient, rendant le débogage difficile.
  • Vous perdez la trace de l’endroit où une variable est modifiée.
  • Les fonctions dépendent d’un état caché (moins prévisible et moins réutilisable).

Dans ces cas, il vaut mieux utiliser :

  • des paramètres de fonction et des valeurs de retour, ou
  • des classes pour encapsuler l’état.

Exemple : Bonnes et Mauvaises Pratiques

Mauvais : variable globale modifiée partout

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
count = 0

def add():
    global count
    count += 1

def multiply():
    global count
    count *= 2

add()
multiply()
print(count)

Ici, le comportement dépend de l’ordre d’appel des fonctions — risqué pour de grands programmes.

Meilleur : utiliser des valeurs de retour ou une classe

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def add(count):
    return count + 1

def multiply(count):
    return count * 2

count = 0
count = add(count)
count = multiply(count)
print(count)

ou en utilisant une classe :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Counter:
    def __init__(self):
        self.value = 0
    def add(self):
        self.value += 1
    def multiply(self):
        self.value *= 2

counter = Counter()
counter.add()
counter.multiply()
print(counter.value)

En Résumé

Situation Faut-il utiliser une variable globale ? Alternative
Définir des constantes ou paramètres fixes Oui
Petits scripts ou analyses ponctuelles Possible
Grandes applications avec état mutable partagé Généralement non Utiliser des classes, valeurs de retour ou modules
Partager des valeurs entre fonctions Parfois Passer comme paramètre

Références

Liens Site
https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces Documentation Python — Portées et Espaces de noms
https://docs.python.org/3/reference/simple_stmts.html#the-global-statement Documentation Python — Référence du mot-clé global
https://docs.python.org/3/reference/simple_stmts.html#the-nonlocal-statement Documentation Python — Référence du mot-clé nonlocal
https://peps.python.org/pep-3104/ PEP 3104 — Accès aux noms dans les portées englobantes (nonlocal)
https://realpython.com/python-scope-legb-rule/ Real Python — Comprendre la portée des variables (règle LEGB)