Variables globales en Python
Apprenez comment fonctionnent les variables globales Python, comment les modifier avec le mot-clé global, éviter les pièges UnboundLocalError et quand utiliser des alternatives.
Les variables globales en Python sont des variables déclarées en dehors de toute fonction. Elles existent pendant toute la durée de vie du programme et peuvent être lues depuis n'importe où — mais les modifier à l'intérieur d'une fonction nécessite le mot-clé global. Cette page explique comment fonctionnent les variables globales, les pièges à éviter et quand recourir à de meilleures alternatives.
Que sont les variables globales ?
Une variable globale est créée au niveau de la portée du module (niveau supérieur) — en dehors de toute fonction ou classe. Tout code dans le même module peut la lire sans déclaration spéciale.
Python utilise la règle LEGB pour résoudre les noms : il cherche dans les portées Local → Enclosing → Global → Built-in dans cet ordre. Une variable globale se trouve au niveau « G », donc chaque fonction peut la trouver après avoir épuisé ses propres portées locales et englobantes. Consultez Python Scope pour une explication complète des quatre niveaux.
Lire vs. modifier des variables globales
Lire une variable globale (toujours possible)
Par défaut, une fonction peut lire n'importe quelle variable globale sans syntaxe particulière :
language = "Python"
def print_language():
print(language) # reads the global
print_language() # Output: PythonLe mot-clé global — requis pour la modification
Si vous essayez d'assigner une valeur à une variable à l'intérieur d'une fonction, Python crée une nouvelle variable locale au lieu de mettre à jour la variable globale. Pour modifier la variable globale, vous devez la déclarer avec le mot-clé global :
counter = 0
def increment():
global counter # tell Python we mean the global 'counter'
counter += 1
print("Counter:", counter)
increment() # Output: Counter: 1
increment() # Output: Counter: 2
print(counter) # Output: 2Sans global counter, la ligne counter += 1 déclencherait une UnboundLocalError car Python essaierait de lire une variable locale appelée counter avant qu'elle ne soit assignée.
Le piège UnboundLocalError
C'est l'erreur la plus courante avec les variables globales. Dès que Python détecte une assignation à un nom à l'intérieur d'une fonction, il traite ce nom comme local dans toute la fonction — même pour les lignes précédant l'assignation :
x = 10
def broken():
print(x) # ERROR — Python sees the assignment below and marks x as local
x = 20
broken()
# UnboundLocalError: local variable 'x' referenced before assignmentCorrigez cela en ajoutant global x en haut de la fonction si vous avez vraiment besoin de modifier la variable globale, ou en renommant la variable locale si vous souhaitez une copie indépendante.
Masquage de variable
Assigner un nom à l'intérieur d'une fonction sans le mot-clé global crée une variable locale qui masque la variable globale — la variable globale n'est pas modifiée :
count = 100
def show_count():
count = 5 # local variable — shadows the global 'count'
print("Inside function:", count) # 5
show_count()
print("Outside function:", count) # 100 — global is unchangedLe masquage n'est pas une erreur, mais peut prêter à confusion. Utilisez des noms distincts pour rendre l'intention évidente.
global dans les fonctions imbriquées
Si vous devez accéder à une variable globale de niveau module depuis une fonction interne (imbriquée), utilisez global — pas nonlocal. nonlocal n'atteint que la portée de la fonction englobante immédiate, pas le niveau module :
total = 0
def outer():
def inner():
global total # reaches module scope
total += 10
inner()
outer()
outer()
print("total:", total) # Output: total: 20Comparez avec nonlocal, qui modifie la variable de la fonction englobante mais laisse la variable globale de niveau module intacte :
x = "global"
def outer():
x = "outer"
def inner():
nonlocal x # modifies outer()'s x, not the module-level x
x = "inner"
inner()
print("outer x after inner():", x) # inner
outer()
print("global x after outer():", x) # global — unchangedPour un examen plus approfondi de nonlocal, consultez Python Scope.
Constantes de niveau module — Le bon cas d'utilisation
L'utilisation la plus légitime des variables globales de niveau module est pour les constantes — des valeurs définies une seule fois et jamais modifiées à l'exécution. Par convention, écrivez-les en UPPER_SNAKE_CASE :
MAX_RETRIES = 3
DEFAULT_TIMEOUT = 30
def connect(host, retries=MAX_RETRIES, timeout=DEFAULT_TIMEOUT):
print(f"Connecting to {host} with {retries} retries, timeout={timeout}s")
connect("db.example.com")
# Output: Connecting to db.example.com with 3 retries, timeout=30sLes constantes n'ont jamais besoin du mot-clé global car vous les lisez seulement, sans les réassigner.
Bonnes pratiques
1. Préférez les arguments de fonction et les valeurs de retour
Passer les données via les signatures de fonctions rend le code plus facile à tester et à comprendre. Cette fonction pure est plus simple que d'utiliser un counter global mutable :
def increment(counter):
return counter + 1
counter = 0
counter = increment(counter)
counter = increment(counter)
print("counter:", counter) # Output: counter: 22. Réservez les variables globales aux vraies constantes à l'échelle du module
Utilisez les variables globales pour les valeurs réellement fixes pour toute la durée du programme (MAX_CONNECTIONS, APP_VERSION, configuration chargée une seule fois au démarrage). Évitez les variables globales mutables qui changent au fil du temps.
3. Utilisez des noms descriptifs en UPPER_SNAKE_CASE pour les constantes
Un nom comme MAX_RETRIES est immédiatement reconnaissable comme une constante de module. Un nom comme r ne l'est pas.
4. Initialisez avant utilisation
Déclarez toutes les variables globales en haut du module, avant toute fonction qui les utilise. Cela évite une NameError si une fonction est appelée avant que la variable n'ait été définie.
5. Soyez prudent avec les threads
Si plusieurs threads appellent des fonctions qui modifient la même variable globale, vous obtenez une condition de course. Protégez l'état mutable partagé avec un threading.Lock, ou repensez la conception pour éviter complètement l'état partagé. Consultez Python Variables pour un aperçu plus large des types de variables en Python.
Résumé
| Situation | Que faire |
|---|---|
| Lire une variable globale dans une fonction | Rien de spécial requis |
| Modifier une variable globale dans une fonction | Ajoutez global <name> en haut de la fonction |
| Modifier la variable d'une fonction englobante | Utilisez nonlocal <name> |
| Partager une valeur fixe entre plusieurs fonctions | Déclarez une constante de niveau module en UPPER_SNAKE_CASE |
| Partager un état mutable entre fonctions | Préférez les arguments de fonction et les valeurs de retour |