Mon Labo Python

Comprendre la portée des variables en python quand on débute enfin

Comprendre la portée des variables en Python, notes prises à la table de cuisine par une débutante en programmation

Je relis la même ligne pour la sixième fois, les doigts encore posés sur le clavier : Python jure que score n'existe pas, alors que je le vois, écrit noir sur blanc, une dizaine de lignes plus haut, dans ce script que j'écris pour m'apprendre Python toute seule, en grande débutante de la programmation. Une odeur de gratin qui a eu le temps de tiédir traîne encore au-dessus des plaques, preuve que j'ai planté la cuisine en plein rangement pour revenir devant mon vieil ordinateur posé sur la table en formica, la tisane refroidissant à côté du cahier de brouillon et des post-it collés près du clavier.

Avant d'aller plus loin, un mot sur ce blog : quelques liens ci-dessous sont affiliés, et si vous achetez une ressource en passant par eux, je touche une petite commission sans que ça change quoi que ce soit au prix pour vous. Je ne parle que des outils qui m'ont vraiment évité de renoncer, comme la Formation au langage Python [Mon point de départ], celle que j'ouvre presque tous les soirs en rentrant.

Pourquoi une variable n'existe pas pour Python alors qu'elle est écrite dans le code

Cette question revient souvent, sous une forme ou une autre, chez les gens qui débutent. La réponse tient à ce qu'on appelle la portée d'une variable, ou son « scope » pour parler comme les tutoriels anglophones : selon l'endroit où elle est créée, Python la range dans une bulle qui reste invisible ailleurs. Pendant longtemps, dans ma tête de débutante, tout ce qui était écrit dans le fichier appartenait à tout le monde. Ce n'est pas le cas : une variable née à l'intérieur d'une fonction reste enfermée dans cette fonction, et dès que celle-ci a fini son travail, la bulle éclate et la variable disparaît avec elle, sans laisser d'adresse.

La portée locale, expliquée avec ce qui traîne sur ma table

Le carnet où je note d'habitude mes temps de cuisson m'a servi à dessiner la solution, un soir où je ne comprenais plus rien : une grande boîte pour tout le fichier, et de petites boîtes fermées à l'intérieur pour chaque fonction. Une variable locale, c'est un secret gardé dans une pièce dont la porte reste close ; pour qu'il sorte, il faut le porter jusqu'au seuil et le confier à quelqu'un d'autre, ce que return fait à ma place. Sans ce mot-clé, la fonction peut très bien afficher un résultat à l'écran avec print, mais rien ne sort réellement de la pièce, et le reste du script n'en saura jamais rien. Ça m'a aussi permis de comprendre pourquoi l'indentation compte tant pour délimiter ces boîtes les unes des autres, même si ce sujet mériterait un carnet entier à lui seul.

Schéma dessiné à la main dans un carnet pour illustrer la portée locale et globale des variables en Python

Si vous sentez que ces histoires de bulles vous échappent encore, il y a une autre entrée qui parle de comment choisir une formation python pour enfin progresser après le travail, et qui aide à remettre un peu d'ordre dans ces idées floues.

Bol de soupe refroidie posé à côté d'un ordinateur affichant un script Python pendant une soirée d'apprentissage

Faire sortir une variable de sa fonction

Perrine, qui me lit depuis Bordeaux et laisse souvent un « moi aussi ! » sous mes billets sur les erreurs de débutante, m'a posé exactement cette question il y a peu. Techniquement, oui : il suffit de renvoyer la valeur avec return, puis de la récupérer dans une variable côté appelant, comme si on ressortait de la pièce fermée avec le secret en main. Ce que j'ignorais avant de m'y confronter, c'est que confondre print et return est sans doute l'erreur la plus fréquente chez les gens qui commencent, moi la première : afficher un résultat donne l'impression que tout fonctionne, alors que rien n'a réellement été transmis au reste du programme.

Le piège des blocs if et for qui ne ferment rien

Une chose m'a beaucoup rassurée quand je m'y suis heurtée : même des personnes qui codent depuis des années se font piéger par cette histoire de portée, parce que Python ne suit pas les mêmes règles que d'autres langages sur ce point précis. Dans certains langages, une variable créée à l'intérieur d'un bloc if ou d'une boucle for reste enfermée dans ce bloc. En Python, ce n'est pas le cas : ces blocs ne créent pas leur propre bulle, et une variable définie dedans reste accessible juste après, à condition que le programme soit effectivement passé par ce chemin-là. Ça ne m'a pas aidée à corriger mon bug plus vite, mais ça m'a fait un bien fou de savoir que je n'étais pas seule à trouver ça déroutant.

À propos du mot-clé global

Il existe un raccourci qui permettrait d'éviter presque tous ces soucis de portée : le mot-clé global, qui dit à une fonction d'aller piocher directement dans une variable extérieure plutôt que d'en fabriquer une nouvelle à elle. Tentant, sur le papier. Mais tout ce que j'ai lu jusqu'ici, y compris ma formation préférée, déconseille d'en abuser : c'est un peu comme laisser toutes les portes de l'appartement ouvertes parce que c'est plus pratique sur l'instant, quitte à se faire surprendre plus tard par un bug qu'on ne voit pas venir. Je m'en sers presque jamais, et à chaque fois que j'ai été tentée, revenir à un return tout simple a réglé le problème plus proprement.

Demander de l'aide à un développeur ne suffit pas toujours

Un ami qui travaille dans l'informatique depuis des années a essayé de m'expliquer tout ça au téléphone, un soir où j'étais bloquée depuis un moment. Ça n'a pas vraiment marché : il est allé beaucoup trop vite, avec un vocabulaire qui supposait que je savais déjà de quoi il parlait, et j'ai raccroché plus perdue qu'avant, en hochant la tête sans rien avoir compris. C'est en revenant à mes propres images de boîtes et de portes fermées, plutôt qu'en essayant de suivre le raisonnement de quelqu'un qui pense déjà comme un développeur, que la portée des variables a fini par se tenir tranquille dans ma tête.

Ce qui s'est mis en place sans déclic soudain

Hier soir, j'ai rouvert le script de la veille, certaine d'avoir tout oublié comme d'habitude, et chaque ligne s'est remise en place toute seule, sans que j'aie besoin d'appeler qui que ce soit à la rescousse. Rien d'aussi net qu'une révélation, plutôt l'impression que les boîtes dessinées dans mon carnet avaient fini par tenir debout toutes seules. J'ai quand même envoyé un message à mon amie Cassandre pour lui raconter cette petite victoire, comme à chaque fois qu'un bout de code accepte enfin de coopérer ; c'est elle qui me répète, chaque fois, qu'apprendre lentement ne veut pas dire apprendre mal, et ça compte plus que n'importe quel tutoriel un soir où j'ai envie de tout abandonner.

Mains d'une débutante en programmation sur le clavier après avoir enfin résolu une erreur de portée de variable en Python

Par curiosité, je suis allée jeter un œil à la formation JavaScript l'autre soir, juste pour voir si d'autres langages géraient ces bulles de la même façon. C'était surtout l'occasion de me rendre compte que je n'ai déjà pas fini d'explorer les miennes en Python, entre les fonctions, les boucles et tout ce qui reste encore flou, alors la comparaison s'arrête là pour ce soir.

La prochaine étape sur ma liste, c'est de réussir à lire un fichier texte en python sans tout faire planter, parce que des variables qui disparaissent, c'est déjà suffisant comme mystère pour ce soir.

Mon script tourne enfin, la cuisine sent toujours un peu le repas du soir, et il est temps de refermer l'ordinateur. Si vous débutez aussi et que ces histoires de bulles vous donnent l'impression de parler à un mur, ça vaut le coup de s'accrocher : parfois, il suffit de dessiner deux ou trois boîtes sur un carnet de cuisine pour que ça s'éclaire. Et si vous cherchez une base solide pour ne plus avancer à tâtons, je continue de recommander la Formation au langage Python, celle qui m'a évité d'abandonner plus d'une fois. Il me reste quand même une question sans réponse pour demain soir : pourquoi l'indentation me joue-t-elle encore des tours alors que je croyais avoir enfin apprivoisé ces bulles ?

Articles connexes