Connexion élèves

Choisir le(s) module(s) à installer :

Notions avancées sur les fonctions

Portée des variables

Un exemple

Observez la sortie du code ci-dessous :

def fonction1(param): a = 3 return param*a a = 5 print(fonction1(a)) print(a)

Comment interpréter le résultat affiché ?

  1. l'instruction print à la ligne 6 affiche le résultat renvoyé par la fonction fonction1, en lui ayant passé la valeur de a comme argument; pas de problème...
  2. l'instruction print à la ligne 7 affiche la valeur de a; mais il y a aussi une variable a dans la fonction : on remarque que ce n'est pas elle qui est affichée, puisqu'on obtient 5 et pas 3.

Ok...et bien, si je veux afficher la variable dans la fonction, je n'ai qu'à lui donner un autre nom :

def fonction2(param): b = 3 return param*b a = 5 print(fonction2(a)) print(b)

Ah, maintenant j'ai une erreur...on dirait que je ne peux pas "accéder" à la variable b....

Et c'est effectivement le cas : en Python, comme dans tous les langages, les variables ont une portée bien définie, c'est à dire une "zone" du code où elles sont accessibles, c'est à dire "utilisables"..

Variables locales

Les variables définies ( = initialisées ) dans une fonction sont appelées variables locales. Elles ne peuvent être utilisées que localement c’est-à-dire qu’à l’intérieur de la fonction qui les a définies.

En fin de fonction, ces variables sont "effacées" par Python et n'existent plus en dehors de la fonction : tenter d’appeler une variable locale depuis l’extérieur de la fonction qui l’a définie provoquera donc une erreur.

Les paramètres d'une fonction sont par définition des variables locales.

Variables globales

Les variables définies ( = initialisées ) dans le programme principal du script, c’est-à-dire en dehors de toute fonction, sont appelées des variables globales.

On peut légitiment penser que leur portée est le script tout entier, fonctions y comprises; c'est le cas, mais à moitié seulement :

def fonction3(param): return param*b def fonction4(param): b = b + 3 return param*b a = 5 b = 3 print(fonction3(a)) print(fonction4(a))
  1. l'appel de la fonction fonction3 ( ligne 10 ) ne pose pas de problème : la fonction renvoie bien le résultat de l'expression param*b, ce qui signifie qu'elle a pu "lire" sans problème le contenu de la variable b, variable globale.
  2. l'appel de la fonction fonction4 ( ligne 11 ) provoque par contre une erreur, à la ligne 5, c'est à dire où on a essayé de modifier la variable globale b.

Les variables globales sont donc accessibles (= utilisables) à travers l’ensemble du script, mais en lecture seulement à l’intérieur des fonctions utilisées dans ce script.

Une fonction va pouvoir utiliser la valeur d’une variable définie globalement mais ne va pas pouvoir modifier sa valeur, c’est-à-dire la redéfinir; si on essaie de redéfinir une variable globale à l’intérieur d’une fonction, on ne fera que créer une autre variable de même nom que la variable globale qu’on souhaite redéfinir mais qui sera locale et bien distincte de cette dernière.

La conséquence de tout ceci est donc que l'on peut très bien donner le même nom à des variables globales et locales ( y compris les paramètres des fonctions ), sans qu'il y ait "collision" entre ces deux noms : ce seront en fait des variables différentes.
Mais on vous a bien dit d'éviter ceci, et de donner des noms différents aux variables locales et globales, afin de pouvoir déboguer plus facilement un code...Soyez rigoureux !

Modifier une variable globale depuis une fonction

Il y a certaines situations où l'on aura besoin pourtant de modifier la valeur d'une variable définie globalement : pensez par exemple au score dans un jeu, qui est généralement défini à 0 dans le programme principal, et que des fonctions du jeu viendront ensuite augmenter ( ou diminuer.. ) :

def augmente_score(points): score += points score = 0 augmente_score(12) print(score)

On rencontre à nouveau l'erreur évoquée précédemment, puisque la variable score n'est pas définie dans la fonction, qui ne peut donc pas la modifier.

La solution est d'utiliser le mot-clé global dans la fonction, qui lui indique que ce que l'on veut modifier est bien la variable globale score, et pas une hypothétique variable locale qui n'existe en fait pas :

def augmente_score(points): global score score += points score = 0 augmente_score(12) print(score)

Et là, ça marche ! Cependant, notez bien que l'on conseille d'éviter au maximum ce genre d'usage des variables globales, c'est un véritable nid à problèmes très difficiles à résoudre...

On peut d'ailleurs très bien s'en passer, en passant la variable globale en argument, et en récupérant la valeur modifiée de la variable comme résultat, que l'on réaffecte alors dans le programme principal à la variable globale :

def augmente_score(sc, points): sc += points # 'sc' est ici bien sûr une variable locale ! return sc score = 0 score = augmente_score(score, 12) print(score)

En résumé...

  • une variable définie dans une fonction est appelée variable locale.
  • une variable définie dans le programme principale est appelée variable globale.
  • la portée d'une variable locale est la fonction où elle a été définie.
  • la portée d'une variable globale est le script tout entier, mais uniquement en lecture seule au sein des fonctions.
  • si on veut ( vraiment... ) modifier une variable globale dans une fonction, on fait précéder le nom de cette variable du mot-clé global avant de la modifier.