Variables locales, variables globales
Exercice
Lisez le code dans l'éditeur puis exécutez-le :
Explication
Les variables a et b ont été définies et la fonction a bien été appelée, où est le problème ?
En fait, les variables définies à l'intérieur d'une fonction n'existent plus dès que le programme a fini d'exécuter cette fonction.
Ici, les variables a et b sont créées dans la fonction mais n'existent pas en dehors de la fonction, d'où l'erreur NameError très explicite.
Observez ce qu'il se passe ici (cliquez sur Next et observez qu'à l'étape 7, les variables a et b disparaissent) :
À retenir
Des variables définies à l'intérieur d'une fonction sont dites locales.
Les variables définies à l’extérieur d’une fonction sont des variables globales. Leur contenu est « visible » de l’intérieur d’une fonction, mais la fonction ne peut pas le modifier.
# ici les variables sont globales
def ma_fonction(param1, param2, ...):
# ici les variables sont locales
# en particulier param1, param2, ... sont des variables locales
# ici les variables sont globales
Exercice
Lisez le code dans l'éditeur et prenez le temps de deviner les valeurs de a, b et c.
# Tests (insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)
Exécutez le script pour vérifier vos réponses.
Explications
Observons ce qu'il se passe pour chacune des variables :
- la variable
aest définie à l'extérieur de la fonction (et avant l'appel de la fonction) donc elle est globale et son contenu est connu dans la fonction (par contre la fonction ne pourrait pas modifier sa valeur) ; - la variable
b: du fait de l'instructionb = 5, il y a création d'une variable localeb, dont la valeur est perdue à la sortie de la fonction ; - avant de se terminer, la fonction renvoie
a * bdonc 4 fois 5 car la variable localebvaut 5 ; - la variable
cest définie à l'extérieur de la fonction donc elle est globale et son contenu est défini par l'affectationc = fonction_bidon().
Ici, la variable b utilisée dans la fonction n'est donc pas la même que celle qui était définie en dehors de cette fonction !
Observez cela à l'étape 7 :
Pour éviter la confusion, il serait peut-être plus pertinent de donner un autre nom à la variable b dans la fonction :
def fonction_bidon():
d = 5
return a * d
a = 4
b = 3
c = fonction_bidon()
mais d'un point de vue des valeurs finales de a, b et c cela ne changera rien.
Exercice
Testez le script :
def fonction_bidon():
b = 7
print(b)
b = 3
fonction_bidon()
# Tests (insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)
puis échangez les deux instructions de la fonction...
Une erreur très subtile
Il faut savoir que lors des affectations dans une fonction, des variables locales sont créées. Voyons cela en modifiant le script précédent.
Script 1
def fonction_bidon():
print(b)
b = 3
fonction_bidon()
la variable b est globale et sa valeur est connue dans la fonction, celle-ci affiche donc 3, logique.
Script 2
def fonction_bidon():
b = 7
print(b)
b = 3
fonction_bidon()
Ici, il y a une affectation (b = 7) donc une variable locale b a été créée et le print est dans la fonction donc c'est la valeur locale de b qui est affichée.
Script 3
def fonction_bidon():
print(b)
b = 7
print(b)
b = 3
fonction_bidon()
Logiquement, la fonction devrait afficher 3 puis 7. Mais au lieu de cela il y a une erreur signalée à la ligne print(b) alors que la même ligne fonctionnait dans le script 2 !
En fait, l'erreur est causée par la ligne suivante (b = 7)... En quelque sorte Python lit deux fois la fonction :
- la première fois, Python n'exécute pas les instructions mais, du fait de l'affectation
b = 7, une variable localebest créée ; - la deuxième fois, Python exécute la première instruction
print(b)mais la variable localebn'a pas de valeur à ce moment-là d'où l'erreur.
Un conseil donc : si vous voulez utiliser des valeurs de variables globales à l'intérieur d'une fonction, passez-les en paramètres :
def fonction_bidon(b):
print(b)
b = 7
print(b)
b = 3
fonction_bidon(b)
Ici b est un paramètre donc une variable locale b est créée dès le début de la fonction et prend la valeur 3 au moment de l'appel de la fonction.
Et, pour plus de clarté, il vaut mieux éviter de modifier les valeurs passées en paramètres :
def fonction_bidon(param):
print(param)
resultat = 7
print(resultat)
Exercice sur le vocabulaire
Associez les éléments du programme avec les termes de vocabulaire.
Exercice
Sans utiliser Python, analysez ce script puis donnez les valeurs finales de a, b et c :
def fonc(a, b):
a = a + 1
b = b - 2
c = a + b
return c
a = 2
b = 1
fonc(a, b)
Quand vous aurez fini, vérifiez avec l'éditeur (avec des print) ou avec Python Tutor.
# Tests (insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)
Exercice
Même consigne :
def une_fonction(e):
f = 3
k = f * e - c
return k
a = 4
c = 5
b = une_fonction(a)
# Tests (insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)