NSI Première

Bonnes pratiques en programmation Python

Comme vous allez pouvoir le constater, la syntaxe de Python est très permissive.
Afin d'uniformiser l'écriture de code en Python, la communauté des développeurs Python recommande un certain nombre de règles afin qu'un code soit lisible.
Lisible par quelqu'un d'autre, mais également, et surtout, par soi-même.
Essayez de relire un code que vous avez écrit « rapidement » il y a un 1 mois, 6 mois ou un an.
Si le code ne fait que quelques lignes, il se peut que vous vous y retrouviez, mais s'il fait plusieurs dizaines voire centaines de lignes, vous serez perdus.

Dans ce contexte, le créateur de Python, Guido van Rossum, part d'un constat simple : « code is read much more often than it is written » (« le code est plus souvent lu qu'écrit »).
Avec l'expérience, vous vous rendrez compte que cela est parfaitement vrai. Alors plus de temps à perdre, voyons en quoi consistent ces bonnes pratiques.

Plusieurs choses sont nécessaires pour écrire un code lisible : la syntaxe, l'organisation du code, le découpage en fonctions mais souvent, aussi, le bon sens.
Pour cela, les « PEP » peuvent nous aider.

Information

Afin d'améliorer le langage Python, la communauté qui développe Python publie régulièrement des Python Enhancement Proposal (PEP), suivi d'un numéro.
Il s'agit de propositions concrètes pour améliorer le code, ajouter de nouvelles fonctionnalités, mais aussi des recommandations sur la manière d'utiliser Python, bien écrire du code, etc.

On va aborder dans cette fiche, sans doute la plus célèbre des PEP, à savoir la PEP 8, qui est incontournable lorsque l'on veut écrire du code Python correctement.

Définition

On parle de code pythonique lorsque ce dernier respecte les règles d'écriture définies par la communauté Python mais aussi les règles d'usage du langage.

De la bonne syntaxe avec la PEP 8

La PEP 8 Style Guide for Python Code est une des plus anciennes PEP (les numéros sont croissants avec le temps).
Elle consiste en un nombre important de recommandations sur la syntaxe de Python.
Il est vivement recommandé de lire la PEP 8 en entier au moins une fois pour avoir une bonne vue d'ensemble.
On ne présentera ici qu'un rapide résumé de cette PEP 8.

1. Indentation

On a vu que l'indentation est obligatoire en Python pour séparer les blocs d'instructions.
Cela vient d'un constat simple, l'indentation améliore la lisibilité d'un code.
Dans la PEP 8, la recommandation pour la syntaxe de chaque niveau d'indentation est très simple : 4 espaces.
N'utilisez pas autre chose, c'est le meilleur compromis.

Attention

Afin de toujours utiliser cette règle des 4 espaces pour l'indentation, il est essentiel de régler correctement votre éditeur de texte.
Consultez pour cela l'annexe Installation de Python disponible en ligne).
Avant d'écrire la moindre ligne de code, faites en sorte que lorsque vous pressez la touche tabulation, cela ajoute 4 espaces (et non pas un caractère tabulation).

2. Importation des modules

Le chargement d'un module se fait avec l'instruction import module plutôt qu'avec from module import * .

Si on souhaite ensuite utiliser une fonction d'un module, la première syntaxe conduit à module.fonction() ce qui rend explicite la provenance de la fonction.
Avec la seconde syntaxe, il faudrait écrire fonction() ce qui peut :

  • mener à un conflit si une de vos fonctions a le même nom ;
  • rendre difficile la recherche de documentation si on ne sait pas d'où vient la fonction, notamment si plusieurs modules sont chargés avec l'instruction
    from module import *

Par ailleurs, la première syntaxe définit un « espace de noms » spécifique au module.

Dans un script Python, on importe en général un module par ligne.
D'abord les modules internes (classés par ordre alphabétique), c'est-à-dire les modules de base de Python, puis les modules externes (ceux que vous avez installés en plus).

Si le nom du module est trop long, on peut utiliser un alias. L'instruction from est tolérée si vous n'importez que quelques fonctions clairement identifiée.

En résumé :

1 import module_interne_1
2 import module_interne_2
3 from module_interne_3 import fonction_specifique
4 from module_interne_4 import constante_1, fonction_1, fonction_2
5
6 import module_interne_1
7 import module_interne_2
8 import module_externe_3_qui_a_un_nom_long as mod3

3. Règles de nommage

Les noms de variables, de fonctions et de modules doivent être de la forme :

1 ma_variable
2 fonction_test_27()
3 mon_module

c'est-à-dire en minuscules avec un caractère « souligné » (« tiret du bas » ou underscore en anglais) pour séparer les différents « mots » dans le nom.

Les constantes sont écrites en majuscules :

1 MA_CONSTANTE
2 VITESSE_LUMIERE

Remarque

  • Le style recommandé pour nommer les variables et les fonctions en Python est appelé snake_case.
    Il est différent du CamelCase utilisé pour les noms des classes et des exceptions (seront vues en terminale).

  • Toutefois, vous pouvez trouvez cette écriture : snakeCase. Attention, la première lettre est une minuscule

Pensez à donner à vos variables des noms qui ont du sens.

Évitez autant que possible les a1, a2, i, truc, toto...
Les noms de variables à un caractère sont néanmoins autorisés pour les boucles et les indices :

In [ ]:
ma_liste = [1, 3, 5, 7, 9, 11]
for i in range(len(ma_liste)):
    print(ma_liste[i])

Bien sûr, une écriture plus « pythonique » de l'exemple précédent permet de se débarrasser de l'indice i

In [ ]:
ma_liste = [1, 3, 5, 7, 9, 11]
for entier in ma_liste:
    print(entier)

Enfin, des noms de variable à une lettre peuvent être utilisés lorsque cela a un sens mathématique (par exemple, les noms x, y et z évoquent des coordonnées cartésiennes).

4. Gestion des espaces

La PEP 8 recommande d'entourer les opérateurs (+, -, /, *, ==, !=, >=, not, in, and, or...) d'un espace avant et d' un espace après.
Par exemple :

1 # code recommandé :
2 ma_variable = 3 + 7
3 mon_texte = "souris"
4 mon_texte == ma_variable
5
6 # code non recommandé :
7 ma_variable=3+7
8 mon_texte="souris"
9 mon_texte== ma_variable

Il n'y a, par contre, pas d'espace à l'intérieur de crochets, d'accolades et de parenthèses :

1 # code recommandé :
2 ma_liste[1]
3 mon_dico{"clé"}
4 ma_fonction(argument)
5
6 # code non recommandé :
7 ma_liste[ 1 ]
8 mon_dico{"clé" }
9 ma_fonction( argument )

Ni juste avant la parenthèse ouvrante d'une fonction ou le crochet ouvrant d'une liste ou d'un dictionnaire :

1 # code recommandé :
2 ma_liste[1]
3 mon_dico{"clé"}
4 ma_fonction(argument)
5
6 # code non recommandé :
7 ma_liste [1]
8 mon_dico {"clé"}
9 ma_fonction (argument)

On met un espace après les caractères : et , (mais pas avant) :

1 # code recommandé :
2 ma_liste = [1, 2, 3]
3 mon_dico = {"clé1": "valeur1", "clé2": "valeur2"}
3 ma_fonction(argument1, argument2)
4
5 # code non recommandé :
6 ma_liste = [1 , 2 ,3]
7 mon_dico = {"clé1":"valeur1", "clé2":"valeur2"}
8 ma_fonction(argument1 ,argument2)

Par contre, pour les tranches de listes (slices), on ne met pas d'espace autour du :

1 ma_liste = [1, 3, 5, 7, 9, 1]
2 # code recommandé :
3 ma_liste[1:3]
4 ma_liste[1:4:2]
5 ma_liste[::2]
6
7 # code non recommandé :
8 ma_liste[1 : 3]
9 ma_liste[1: 4:2 ]
10 ma_liste[ : :2]
In [ ]:
ma_liste = [1, 3, 5, 7, 9, 1]
In [ ]:
ma_liste[ : :2]

Enfin, on n' ajoute pas plusieurs espaces autour du = ou des autres opérateurs pour faire joli :

1 # code recommandé :
2 x1 = 1
3 x2 = 3
4 x_old = 5
5 
6 # code non recommandé :
7 x1    = 1
8 x2    = 3
9 x_old = 5

5. Longueur de ligne

Une ligne de code ne doit pas dépasser 79 caractères, pour des raisons tant historiques que de lisibilité.

Le caractère \ permet de couper des lignes trop longues.
Par exemple :

In [ ]:
ma_variable = 3
if ma_variable > 1 and ma_variable < 10 \
and ma_variable % 2 == 1 and ma_variable % 3 == 0:
    print("ma variable vaut {}".format(ma_variable))

En utilisant des parenthèses.
À l'intérieur d'une parenthèse, on peut revenir à la ligne sans utiliser le caractère \.
C'est particulièrement utile pour préciser les arguments d'une fonction ou d'une méthode, lors de sa création ou lors de son utilisation :

1 def ma_fonction(argument_1, argument_2,
2                 argument_3, argument_4):
3        return argument_1 + argument_2
In [ ]:
def ma_fonction(argument_1, argument_2,
               argument_3, argument_4):
    return argument_1 + argument_2

ma_fonction("texte très long", "tigre",
            "singe", "souris")

Les parenthèses sont également très pratiques pour répartir sur plusieurs lignes une chaîne de caractères qui sera affichée sur une seule ligne :

In [ ]:
print("ATGCGTACAGTATCGATAAC"
      "ATGACTGCTACGATCGGATA"
      "CGGGTAACGCCATGTACATT")

Notez qu'il n'y a pas d'opérateur + pour concaténer les trois chaînes de caractères et que celles-ci ne sont pas séparées par des virgules.

À partir du moment où elles sont entre parenthèses, Python les concatène automatiquement.

On peut aussi utiliser les parenthèses pour évaluer un expression trop longue :

In [ ]:
ma_variable = 3
if (ma_variable > 1 and ma_variable < 10
    and ma_variable % 2 == 1 and ma_variable % 3 == 0):
    print("ma variable vaut {}".format(ma_variable))

Enfin, il est possible de créer des listes ou des dictionnaires sur plusieurs lignes, en sautant une ligne après une virgule :

1 ma_liste = [1, 2, 3,
2             4, 5, 6,
3             7, 8, 9]
4
5 mon_dico = {"clé1": 13,
6             "clé2": 42,
7             "clé3": -10}

6. Lignes vides

Dans un script, les lignes vides sont utiles pour séparer visuellement les différentes parties du code.

Il est recommandé de laisser deux lignes vides avant la définition d'une fonction ou d'une classe et de laisser une seule ligne vide avant la définition d'une méthode (dans une classe).

On peut aussi laisser une ligne vide dans le corps d'une fonction pour séparer les sections logiques de la fonction, mais cela est à utiliser avec parcimonie.

7. Commentaires

Les commentaires débutent toujours par le symbole # suivi d'un espace.
Ils donnent des explications claires sur l'utilité du code et doivent être synchronisés avec le code, c'est-à-dire que si le code est modifié, les commentaires doivent l'être aussi (le cas échéant).

Les commentaires sont sur le même niveau d'indentation que le code qu'ils commentent.
Les commentaires sont constitués de phrases complètes, avec une majuscule au début (sauf si le premier mot est une variable qui s'écrit sans majuscule) et un point à la fin.

La PEP 8 recommande très fortement d'écrire les commentaires en anglais, sauf si vous êtes à 120% sûr que votre code ne sera lu que par des francophones. Dans la mesure où vous allez souvent développer des programmes scientifiques, nous vous conseillons d'écrire vos commentaires en anglais.

Soyez également cohérent entre la langue utilisée pour les commentaires et la langue utilisée pour nommer les variables. Pour un programme scientifique, les commentaires et les noms de variables sont en anglais. Ainsi ma_liste deviendra my_list et ma_fonction deviendra my_function (par exemple).

Les commentaires qui suivent le code sur la même ligne sont à éviter le plus possible et doivent être séparés du code par au moins deux espaces :

x = x + 1   # My wonderful comment.