Programmation en Python

Notion de script

On peut utiliser Python en mode interactif, à la manière d’une calculatrice. Les instructions (ou commandes) sont ainsi, l’une après l’autre, entrées au clavier, interprétées et suivies d’un résultat souvent réutilisé par la suite.

Mais si elle en vaut la peine, une séquence d’instructions peut être sauvegardée dans un fichier texte, avec l’extension py. On parle alors d’un script. On peut ouvrir ce script et l’exécuter, de façon automatisée, comme si les instructions qu’il contient étaient à nouveau entrées au clavier (chronologiquement de la première à la dernière ligne).

Ce script contient essentiellement des définitions de fonctions. Quand le script aura été lu, on pourra utiliser ces fonctions (dans le mode interactif, essentiellement), exactement comme si ces fonctions faisaient partie du langage (elles en deviennent une sorte d’extension).

Utilité des commentaires

La définition d’une fonction peut être très simple (se résumer à quelques lignes) ou au contraire être relativement longue. Il est important que le code qu’elle contient soit commenté (pour favoriser la relecture ultérieure, ou simplement parce que ce code doit être soumis à la lecture d’un correcteur.

Les commentaires sont insérés dans le script, à l’intérieur de la définition d’une fonction (pour expliquer un passage important), ou entre deux définitions de fonctions.

  • En Python, un commentaire commence par le symbole # et se poursuit jusqu’à la fin de la ligne.
  • Il est également possible de définir un commentaire sous la forme d’une chaîne de caractère spéciale, pouvant courir sur plusieurs lignes, commençant et finissant par ‘ ‘ ‘.
    Cette chaîne facultative, appelée docstring, est alors attachée à la fonction et pourra servir à décrire le rôle de celle-ci, les arguments qu’elle reçoit, et le résultat qu’elle renvoie. Si cette fonction s’appelle mafonction, cette description sera affichée par l’instruction help(mafonction).

On évitera les commentaires qui ne sont que des paraphrases du code. Par exemple, dans une fonction Python, on n’écrira pas :

Notions sur l’indentation du code

Dans de nombreux langages de programmation (dans tous?), on est amené à grouper des instructions successives, et à considérer ce groupe comme une seule méta-instruction. Mais encore faut-il trouver un moyen de marquer (par des éléments du langage et/ou par des dispositions visuelles) les limites d’un tel groupe d’instructions.

Notons par exemple groupe une suite d’instructions

Imaginons également une condition test, vraie ou fausse à un moment donné du déroulement du script. On cherche à écrire une séquence d’instructions du genre :

Voici deux formulations possibles.

Cette première solution est pour le moins ambiguë (est-ce qu’on évalue uniquement instruction_1 si la condition test est vraie?).

Cette deuxième solution est correcte car elle indique clairement les limites du groupe d’instructions à évaluer si la condition test est vraie.

Il est d’usage d’accentuer visuellement le groupe par une légère indentation (décalage vers la droite).

Il faut un moyen non ambigu de poser les limites d’un groupe d’instructions.

Dans les exemples précédents, instruction_1 ; . . . ; instruction_p peuvent également être des instructions composées, et donc contenir des groupes (des blocs) d’instructions.

Chaque instruction du programme figure donc à un certain niveau de profondeur (si on convient que le niveau initial est le niveau 0, on trouvera des instructions de niveau 1, de niveau 2, etc.). Ces niveaux sont d’autant plus faciles à identifier pour le lecteur que le programmeur aura pris soin de les marquer visuellement par des indentations progressives.

Dans la plupart des langages, ces indentations n’ont rien d’obligatoire : elles constituent un simple confort visuel. Elles peuvent varier légèrement, à l’intérieur d’un même bloc, sans conséquence pour la logique du programme.

En Python, l’indentation est obligatoire

La solution apportée par Python au problème précédent est radicale :

Dans un même bloc, deux instructions de même profondeur logique doivent avoir strictement la même indentation.

Avec une telle convention, il est inutile de marquer le début et la fin d’un bloc par des éléments du langage. Dans ce qui suit, il va être question de “blocs” qui sont sous le contrôle d’une ligne d’en-tête. En Python, les lignes d’en-tête sont essentiellement (voir plus loin pour une présentation plus détaillée) :

Le début de la définition d’une fonctiondef mafonction(param) :
Le début d’une instruction “si condition”if condition :
Le début d’une instruction “sinon si”elif condition :
Le début d’une instruction “sinon”else condition :
Le début d’une instruction “tant que”while condition :

Le bloc qui suit une ligne d’en-tête peut se réduire à une seule instruction. Dans ce cas, il est possible de le placer à la suite du caractère “deux-points” qui termine la ligne d’en-tête.

On évitera d’utiliser des tabulations (plutôt que des espaces) pour l’indentation des blocs ! En Python, le degré d’indentation standard est de quatre espaces vers la droite.

On veillera à un respect scrupuleux des indentations, mais on est aidé en cela par l’éditeur de Python, qui augmente automatiquement l’indentation après chaque instruction d’en tête, et qui conserve cette indentation à l’intérieur du bloc courant. Pour sortir d’un bloc (donc diminuer l’indentation), un simple appui sur la touche d’effacement arrière suffit.

L’écriture des fonctions en Python

L’écriture d’une fonction en Python suit souvent le modèle ci-contre.
Les instructions sont évaluées dans l’ordre successif des lignes.
La dernière ligne renvoie une valeur : c’est le résultat de la fonction.

Une des erreurs les plus classiques consiste à oublier cette ligne return.
Si celle ligne est absente, tout se passe comme si on terminait par return None (c’est-à-dire “renvoyer rien”, ce qui est tout à fait possible, mais plutôt rare, et n’est en général pas l’intention de la personne qui a écrit le programme).

On ne confondra pas return et print, car print est un “effet”, et donc ne renvoie pas de valeur (plus précisément il renvoie la valeur None). Les instructions qui composent la fonction sont exécutées dans l’ordre naturel.

Comme on va le voir ci-après, ces instructions peuvent être des étiquettes (ifwhilefor) suivies par un bloc. Il est très possible de sortir prématurément de la fonction par une instruction return située quelque part dans un bloc.

Voici par exemple une fonction trouve qui prend en argument un objet a et une liste L et qui renvoie True si l’objet a figure quelque part dans la liste, et False s’il n’y figure pas. On parcourt la liste L et on renvoie True dès que a est trouvé. Si on sort de la boucle for, c’est que a n’est pas dans L et à ce moment là on termine la fonction en renvoyant False.