Analysez le programme suivant :
def fct():
i=5
fct()
Après avoir exécuté le programme ci-dessus, déterminez la valeur référencée par la variable i en utilisant la console.
Comme vous avez pu le constater, nous avons eu droit à une erreur : "NameError: name 'i' is not defined". Pourquoi cette erreur, la variable i est bien définie dans la fonction fct() et la fonction fct() est bien exécutée, où est donc le problème ?
En faite, la variable i est une variable dite locale : elle a été définie dans une fonction et elle "restera" dans cette fonction. Une fois que l'exécution de la fonction sera terminée, la variable i sera "détruite" (supprimée de la mémoire). Elle n'est donc pas accessible depuis "l'extérieur" de la fonction (ce qui explique le message d'erreur que nous obtenons).
Autre exemple de cette notion de variable locale :
Analysez le programme suivant :
i = 3
def fct():
i=5
fct()
Après avoir exécuté le programme ci-dessus, déterminez la valeur référencée par la variable i en utilisant la console.
Cette fois pas d'erreur, mais à la fin de l'exécution de ce programme, la variable i référence la valeur 3. En faite dans cet exemple nous avons 2 variables i différentes : la variable i "globale" (celle qui a été définie en dehors de toute fonction) et la variable i "locale" (celle qui a été définie dans la fonction). Ces 2 variables portent le même nom, mais sont différentes.
Une variable globale peut être "utilisée" à l'intérieur d'une fonction :
Analysez et testez le programme suivant :
i = 3
def fct():
print(i)
fct()
Quand on cherche à utiliser une variable dans une fonction, le système va d'abord chercher si cette variable se "trouve" dans l'espace local de la fonction, puis, s'il ne la trouve pas dans cet espace local, le système va aller rechercher la variable dans l'espace global. Pour le "print(i)" situé dans la fonction le système ne trouve pas de variable i dans l'espace local de la fonction "fct", il passe donc à l'espace global et trouve la variable i (nous avons donc 3 qui s'affiche). Il est important de bien comprendre que si le système avait trouvé une variable i dans l'espace local de la fonction, la "recherche" de la variable i se serait arrêtée là :
Analysez et testez le programme suivant :
i = 3
def fct():
i = 5
print(i)
fct()
Analysez et testez le programme suivant :
i = 3
def fct():
i = i + 1
fct()
Nous avons une erreur "UnboundLocalError: local variable 'i' referenced before assignment"
Pour pouvoir modifier une variable globale dans une fonction, il faut utiliser l'instruction "global" :
Analysez le programme suivant :
i = 3
def fct():
global i
i = i + 1
fct()
Après avoir exécuté le programme ci-dessus, déterminez la valeur référencée par la variable i en utilisant la console.
En faite, l'utilisation de "global" est une (très) mauvaise pratique, car cette utilisation peut entrainer des "effets de bord".
On parle d'effet de bord quand une fonction modifie l'état d'une variable globale. Dans notre exemple ci-dessus la fonction fct modifie bien la valeur référencée par la variable i : avant l'exécution de fct, la variable i référence la valeur 5, après l'exécution de la fonction fct la variable i référence la valeur 6. Nous avons donc bien un effet de bord.
Autre exemple plus "classique" (sans avoir à utiliser le "global") d'un effet de bord en Python :
Analysez le programme suivant :
t = [1, 2, 3]
def fct():
t.append(4)
fct()
Après avoir exécuté le programme ci-dessus, déterminez la valeur référencée par la variable t en utilisant la console.
Nous avons bien ci-dessus un effet de bord puisque le tableau t est modifié par une fonction.
Les effets de bord c'est "mal" ! Mais pourquoi est-ce "mal" ?
Les effets de bords provoquent parfois des comportements non désirés par le programmeur (évidemment dans des programmes très complexes, pas dans des cas simplistes comme celui que nous venons de voir dans le "À faire vous-même 6"). Ils rendent aussi parfois les programmes difficilement lisibles (difficilement compréhensibles). À cause des effets de bord, on risque de se retrouver avec des variables qui référenceront des valeurs qui n'étaient pas prévues par le programmeur. On dit aussi qu'à un instant donné, l'état futur des variables est difficilement prévisible à cause des effets de bord.
Un paradigme de programmation se propose d'éviter au maximum les effets de bords : la programmation fonctionnelle.
Auteur : David Roche