Variables locales et variables globales
Premier exemple :
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 fait, 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).
Une variable définie dans une fonction est locale.
Elle ne peut pas être utilisée en dehors de la fonction.
Deuxième exemple :
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 fait, 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 définie localement dans une fonction peut porter le même nom qu'une variable globale. Dans ce cas, ce sont deux variable distinctes mais de même nom (ce qui n'est pas une bonne pratique).
Troisième exemple :
Exécutez le programme suivant :
La variable i est définie en dehors de la fonction, elle est globale.
Une variable globale peut être "utilisée" à l'intérieur d'une fonction.
Quatrième exemple :
Avant d'exécutez le programme ci-dessus, déterminez la valeur référencée par la variable i en fin d'exécution
Pour le "print(i)" situé dans la fonction le système trouve une variable i dans l'espace local de la fonction "fct", et il utilise donc celle ci, même s'il existe une variable globale i. Il est important de bien comprendre que le lorsque système trouve une variable i dans l'espace local de la fonction, la "recherche" de la variable i s'arrête là. D'autre part, ici nous avons deux variable i : l'une globale, définie en dehors de fct(), une autre locale, définie dans fct(). Lorsque la fonction s'arrête, la variable locale est détruite, la variable globale demeure et n'a pas été modifiée.
Cliquez Visualiser et observez l'état de la mémoire au cours de l'exécution.
Cinquième exemple :
Exécutez le programme ci-dessus, déterminez la valeur référencée par la variable i en fin de programme.
Nous avons une erreur "UnboundLocalError: local variable 'i' referenced before assignment"
Cinquième exemple (avec global)
Exécutez maintenant cette seconde version de l'exemple 5 :
Pour pouvoir modifier une variable globale dans une fonction, il faut utiliser l'instruction "global"
En fait, l'utilisation de "global" est une (très) mauvaise pratique, car cette utilisation peut entraîner des "effets de bord".
Effet de bord
On parle d'effet de bord (c'est une bien mauvaise traduction de side effet, on devrait dire effets secondaires) 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.
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). 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.
En résumé, on évitera autant que possible l'utilisation du "global".
Un paradigme de programmation se propose d'éviter au maximum les effets de bords : la programmation fonctionnelle. Nous étudierons ce paradigme de programmation très prochainement.