Aller au contenu

Variables locales, variables globales⚓

Exercice

Lisez le code dans l'éditeur puis exécutez-le :

###
def fonctionpy-undbidon():bksl-nl a = 8bksl-nl b = 5bksl-nlbksl-nlfonctionpy-undbidon()bksl-nlprint("a vaut", a)bksl-nlprint("b vaut", b)bksl-nl

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.

🐍 Script Python
# 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.

###
def fonctionpy-undbidon():bksl-nl b = 5bksl-nl return a py-str bbksl-nlbksl-nla = 4bksl-nlb = 3bksl-nlc = fonctionpy-undbidon()bksl-nlbksl-nlprint("a vaut", a)bksl-nlprint("b vaut", b)bksl-nlprint("c vaut", c)bksl-nl

Exécutez le script pour vérifier vos réponses.

Explications

Observons ce qu'il se passe pour chacune des variables :

  • la variable a est 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'instruction b = 5, il y a crĂ©ation d'une variable locale b, dont la valeur est perdue Ă  la sortie de la fonction ;
  • avant de se terminer, la fonction renvoie a * b donc 4 fois 5 car la variable locale b vaut 5 ;
  • la variable c est dĂ©finie Ă  l'extĂ©rieur de la fonction donc elle est globale et son contenu est dĂ©fini par l'affectation c = 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 :

🐍 Script Python
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 :

🐍 Script Python
def fonction_bidon():
    b = 7
    print(b)

b = 3
fonction_bidon()

###

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

🐍 Script Python
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

🐍 Script Python
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

🐍 Script Python
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 locale b est crĂ©Ă©e ;
  • la deuxiĂšme fois, Python exĂ©cute la premiĂšre instruction print(b) mais la variable locale b n'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 :

🐍 Script Python
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 :

🐍 Script Python
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 :

🐍 Script Python
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.

###

Exercice

MĂȘme consigne :

🐍 Script Python
def une_fonction(e):
    f = 3
    k = f * e - c
    return k

a = 4
c = 5
b = une_fonction(a)

###