Variables locales et globales
Variables locales et globales
Objectifs cantonaux : O1.6.
Cours complet sur la plateforme Runestone de Cédric Donner : Variables locales et globales.
Une variable n’existe pas forcément partout dans un programme : selon l’endroit où elle est créée, elle est visible et modifiable depuis des endroits différents. C’est la distinction entre variables locales et globales.
▷ Définition — Variable locale
Une variable locale appartient en propre à une fonction. Elle peut être créée de deux manières :
- en tant que paramètre de la fonction (les paramètres sont des variables locales) ;
- en étant définie à l’intérieur du corps de la fonction, par une affectation
variable = ....
Une variable locale n’existe que pendant l’exécution de la fonction à laquelle elle appartient : dès que la fonction termine, ses variables locales sont détruites. Elle n’est visible que depuis l’intérieur de cette fonction.
▷ Définition — Variable globale
Une variable globale est définie en dehors de toute fonction, au niveau principal du programme. Par défaut, une fonction ne peut pas modifier la valeur d’une variable globale depuis son intérieur (seulement la lire).
Devinette 1
Que fait ce programme, et qu’affiche-t-il ?
def double(x):
x = x * 2
print(x)
x = 10
double(x)
print(x)! Un piège classique
Il y a deux variables différentes nommées x dans ce programme : la variable globale x (ligne 5) et la variable locale x, propre à la fonction double, qui n’existe que pendant l’exécution de double(x) (ligne 2). Elles portent le même nom mais ne sont pas la même variable.
Le programme affiche donc :
20
10
double(x) reçoit la valeur de x (10), la double dans sa propre variable locale, l’affiche (20) — mais cela ne change rien à la variable globale x, qui vaut toujours 10 à la fin.
Devinette 2
Même question pour ce programme un peu plus subtil :
def f(x):
y = 10
y += 5
x = y
print(x)
print(y)
x = 10
f(x)
print(x)
print(y)! Attention à la dernière ligne
À l’intérieur de f, x et y sont deux variables locales : la fonction affiche 15 puis 15. Mais après l’appel, print(x) (variable globale) affiche à nouveau 10 — inchangé. Quant à print(y), il provoque une erreur (NameError) : la variable y n’a jamais été créée en dehors de la fonction f, elle n’existe donc pas au niveau global.
Devinette 3 — modifier une variable globale depuis une fonction
def f(x):
y += 10
print(x)
x = 10
y = 5
f(x)
print(x)! Erreur garantie
Cette fois, le programme provoque une erreur dès l’appel de f(x) : y += 10 équivaut à y = y + 10, ce qui suppose de lire y avant de lui réaffecter une valeur. Or Python considère que, dès qu’une fonction affecte une valeur à un nom de variable (même avec +=), cette variable est locale à la fonction — sauf indication contraire. Comme aucune variable locale y n’a encore de valeur au moment de y += 10, Python lève une erreur : impossible de lire une variable qui n’a pas encore été créée dans ce contexte.
Question de compréhension
Un programmeur veut dessiner nb_cercles cercles concentriques, mais son programme ne fait pas ce qu’il attend :
from math import pi
from gturtle import *
def polygone(cote, nb_cotes):
for _ in range(nb_cotes):
forward(cote)
right(360 / nb_cotes)
def cercle(rayon):
setPos(-rayon, 0)
nb_cotes = 60
polygone(2 * pi * rayon / nb_cotes, nb_cotes)
rayon += 30
def cercles_concentriques(nb_cercles):
rayon = 50
for _ in range(nb_cercles):
cercle(rayon)
hideTurtle()
cercles_concentriques(5)Tous les cercles sont dessinés au même rayon (50), au lieu d’être de plus en plus grands. Expliquez pourquoi, puis corrigez le programme.
! Piste
rayon dans cercle(rayon) est un paramètre, donc une variable locale à cercle. La ligne rayon += 30 modifie bien cette copie locale, mais cette modification est perdue dès que cercle se termine : la variable rayon de cercles_concentriques n’est jamais mise à jour. La correction consiste à augmenter rayon dans cercles_concentriques elle-même, après chaque appel à cercle(rayon).