• 8 heures
  • Facile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 19/03/2024

Écrivez du code Python qui s’explique tout seul

Respectez les conventions de nommage

Comme nous l’avons vu avec notre exemple sur les années bissextiles, le fait de choisir des noms logiques pour vos variables, classes et fonctions, est très utile à toute personne qui lit votre code. De plus, la PEP 8 recommande ce qui suit :

  • Écrivez les noms de variables en minuscules, avec des underscores (tirets bas). C'est ce qu'on appelle la convention « snake_case » :

name = "Jeanne"
fuel_level = 100
famous_singers = ["Céline Dion", "Michael Jackson", "Edith Piaf"]
  • Écrivez les variables constantes en majuscules, avec des underscores :

DAYS_PER_WEEK = 7
PERSONAL_EMAIL = "myemail@email.com"
  • Écrivez les noms de classe avec une majuscule au début de chaque mot, sans ponctuation (la convention « CapitalizedCase ») :

class JukeBox:
    pass

class SpaceShip:
    pass
  • Écrivez les noms de modules en minuscules, en évitant au maximum l’utilisation des underscores :

# Exemples pris de la bibliothèque standard de Python
import os
import sys
import shutil  # contraction de “sh” (langage bash) et “util”
import pathlib  # contraction de “path” et “lib”

Les romans sont écrits avec des majuscules et des règles de ponctuation cohérentes, pour les rendre plus faciles à lire. Même si votre code n’est pas destiné à devenir un livre de chevet, vous simplifierez les choses pour les développeurs à venir, en suivant ces règles.

En Python, on ne crée pas de variables dont la valeur ne peut pas être modifiée. Cependant, si vous voulez qu’une valeur demeure constante, le simple fait de l’écrire TOUT_EN_MAJUSCULES signale aux autres développeurs de ne pas écrire du code qui la modifie. Et, grâce à la PEP 8, ils devraient le comprendre. 🙂

On recommande également d’éviter les abréviations de ce type :

def mltply(first, second):
    return first * second

On les évite car elles peuvent prêter à confusion, et demandent de faire un effort de traduction pour les comprendre. N’oubliez pas que le code est lu bien plus souvent qu’il n’est écrit : évitons donc de nous compliquer la tâche avec des abréviations, des mots hachés et des variables à une lettre. Le temps “gagné” sur le moment ne rattrapera jamais le temps perdu à relire ; et la qualité générale du code s’en ressentira. 😉

Expliquez avec des commentaires et de la documentation

Comme nous l’avons vu précédemment dans l’exemple sur les années bissextiles, il est utile de laisser un commentaire pour expliquer les parties de votre code qui ne sont pas immédiatement évidentes.

# Les années bissextiles sont toutes des multiples de 4

Néanmoins, les commentaires peuvent aussi vous distraire et ne pas vous aider :

score += 10   # ajoute 10 au score

Que nous dit la sagesse collective de la communauté Python à ce sujet dans la PEP 8 ?

  • Écrivez des phrases complètes en anglais (sauf s’il s’agit de code interne à une équipe qui préfère une autre langue).

  • Évitez les commentaires qui contredisent le code. La PEP 8 est formelle : « Un commentaire qui contredit le code est pire que de ne pas en mettre ».

Mais pourquoi est-ce que quelqu’un commenterait en contredisant le code ?

Ce serait bête de le faire intentionnellement, bien sûr. Mais ce qui peut facilement se passer avec les commentaires superflus, c’est que quelqu’un mette à jour le code, et oublie de mettre à jour le commentaire. Vous vous retrouvez alors avec des choses absurdes comme celle-ci :

score += 40   # ajoute 10 au score

Ce qui nous amène à nos bonnes pratiques suivantes :

  • Mettez les commentaires à jour lorsque le code change.

  • Évitez les commentaires sur la même ligne que le code, ils font négligé.

  • Mettez un seul espace entre le symbole dièse et le texte (pour différencier du code qui a été commenté).

  • Utilisez le même niveau d’indentation que la ligne de code qui suit, pour une bonne lisibilité :

# Commentaire correctement indenté
def foo(arg):
    # Commentaire correctement indenté
    pass

    # Commentaire mal indenté
def foo(arg):
# Commentaire mal indenté
    pass

Utilisez des chaînes de documentation (« docstrings »)

Avez-vous déjà vu ce type de commentaire ?

def multiply(first, second=1):
    """Multiplie deux nombres.
 
    Args:
        first -- le multiplicande
        second -- le multiplicateur (défaut 1)
    """
    return first * second
 
print(multiply(13, 77))
print(multiply.__doc__)

Les lignes entres les séries de trois guillemets et colorisées en jaune sont des docstrings – des commentaires spéciaux écrits au tout début d’une fonction, d’une classe ou d’un module, et utilisés pour la documentation. Les docstrings permettent de décrire votre code. Elles permettent aussi aux outils automatisés d’accéder au texte, par exemple pour générer une documentation en ligne de votre code.

Les docstrings ne sont pas réservées qu’aux projets de grande ampleur : elles sont vos alliées de tous les jours pour vous aider à comprendre votre code, sans avoir à vous plonger dans le code source. Bien évidemment, elles sont d’autant plus indispensables dans les projets d’équipe !

Attendez – je pensais que les commentaires n’avaient aucun effet sur le code. Comment ces outils peuvent-ils accéder à mes docstrings ?

Les docstrings en début de fonction ou de classe sont spéciales, et on peut y accéder en utilisant l’attribut  __doc__  :

print(multiply.__doc__)

Quand est-ce que je dois utiliser les docstrings ?

Selon la PEP 257, il est bon d’utiliser les docstrings partout. 😊

Je dois créer mes docstrings à chaque module, classe, fonction et méthode ? C’est quand même beaucoup de travail en plus ! Et puis, je connais mon code…

Les docstrings apportent une couche de documentation à votre code, elles seront toujours un gain qualitatif et une aide dans votre projet. Voyez-les comme autant de phares dans la nuit. On peut naviguer de nuit sans phare, mais c’est bien moins sécurisant. 😉

Mon conseil : vous pouvez ne pas en mettre dans les méthodes « privées » de vos classes.

Savoir écrire une docstring, c’est aussi savoir expliquer son code. Les docstrings sont donc un bon moyen de garder un recul dans notre façon de coder. Expliquer son code à soi-même évite bon nombre de bugs, en témoigne la fameuse méthode du canard en plastique. 🦆

Pour finir, je vais vous exposer les deux manières de créer des docstrings :

  • les docstrings sur une ligne (pour les cas les plus évidents) ;

  • les docstrings sur plusieurs lignes (pour les cas plus complexes).

La première méthode va peut-être intéresser les plus pressés d’entre nous : il suffit d’une simple phrase monoligne, en mode impératif. Notez que la docstring ne doit jamais décrire le fonctionnement interne de sa fonction ou méthode, mais seulement son retour. Il ne s’agit pas ici d’expliquer le code, mais d’expliquer son usage. C’est tout son intérêt.

La deuxième méthode n’est qu’une extension de la première. Nous reprenons le principe de la phrase simple en première ligne. Puis nous ajoutons des explications plus précises, et documentons les paramètres, les retours et les exceptions.

Appliquez votre nouvelle connaissance

Vous vous rappelez d’un vieux film génial dont vous n’avez qu’une partie du nom. Par chance, vous avez créé une fonction  search_film  qui prend un nom et recherche dans la base de données de films. Voici à quoi elle pourrait ressembler :

def search_film(name):
    films = Film.filter_by_name(name)
    if films:
        return films.pop(0)
return None

Bien que son nom est assez équivoque, nous pourrions la documenter avec une docstring. Quelle docstring suggérez-vous ?

Si vous n’avez pas d’idées, vous pouvez vous baser sur le nom de la fonction (pour peu qu’il soit explicite !) :

def search_film(name):
    """Cherche un film."""
    # ...

C’est un bon début, et ça peut parfois convenir si la fonction est très simple et que vous n’avez pas plus d’idées : votre code possède au moins une documentation. Mais vous conviendrez que ce n’est pas très qualitatif. Quelle amélioration pouvez-vous faire ?

Eh bien, nous pouvons par exemple prendre en compte le·s paramètre·s dans la phrase explicative :

def search_film(name):
    """Cherche un film selon un nom donné."""
    # ...

C’est mieux ! Maintenant la signature de la fonction est bien expliquée, et la docstring apporte une réelle plus-value sur la signature.

Il reste cependant un flou : qu’est ce que la fonction peut bien retourner ? Un booléen pour dire qu’un film a été trouvé, le nom du film, un objet « film » ? Les possibilités sont multiples et propres à chaque situation… 🤷‍♀️

Remédions à ça !

def search_film(name):
    """Cherche un film selon un nom donné.
 
    Retourne un objet film si un film a été trouvé, sinon None.
    """
    # ...

Plus de place pour l’interprétation : la docstring est bien descriptive. Nous pouvons très clairement nous contenter de ce résultat. 🙌

Voici enfin une autre version, plus complète, qui suit la convention Google sur les docstrings :

def search_film(name):
    """Cherche un film selon un nom donné.
 
    Attrs:
    - name (str): le nom utilisé pour la recherche.
 
    Returns:
    - un objet `film` si un film a été trouvé, ou None.
    """
    # ...

Plus normée, plus cadrée. C’est loin d’être une obligation, mais ça peut aider lorsqu’une fonction gagne en complexité.

En résumé

  • Les variables, classes et modules doivent porter des noms utiles et écrits selon le style suggéré.

  • Les commentaires doivent être utilisés avec modération, maintenus à jour, et indentés de la même façon que la ligne de code suivante.

  • Les docstrings sont des commentaires spéciaux, auxquels on peut accéder avec  __doc__  .

  • À l’inverse des commentaires, usez et abusez des docstrings ! 😊

Au chapitre suivant, nous verrons comment présenter un fichier Python de façon agréable et utile pour les personnes qui le lisent 

Exemple de certificat de réussite
Exemple de certificat de réussite