Documenter son code Python avec les Docstrings : Guide Complet

Apprenez a ecrire des docstrings efficaces en Python. Decouvrez les conventions PEP 257, les formats Google, NumPy et reStructuredText, et comment generer une documentation automatique.

Mahmoud DEVO
Mahmoud DEVO
December 27, 2025 7 min read
Documenter son code Python avec les Docstrings : Guide Complet

Introduction

La documentation est un aspect essentiel du developpement logiciel professionnel. En Python, les docstrings (chaines de documentation) constituent le mecanisme standard pour documenter les modules, classes, fonctions et methodes directement dans le code source.

Une docstring est une chaine de caracteres litterale qui apparait comme premiere instruction dans un module, une fonction, une classe ou une methode. Python stocke automatiquement cette chaine dans l’attribut special __doc__ de l’objet, la rendant accessible a la fois aux developpeurs et aux outils de generation de documentation.

Contrairement aux commentaires qui sont ignores par l’interpreteur, les docstrings font partie integrante de l’objet Python et peuvent etre accedees programmatiquement via la fonction help() ou l’attribut __doc__.

Dans cet article, nous explorerons en profondeur les conventions de docstrings, les differents formats populaires, et les meilleures pratiques pour documenter efficacement votre code Python.

Syntaxe de base des Docstrings

Docstrings simples (une ligne)

Pour les fonctions et methodes simples, une docstring sur une seule ligne suffit :

def carre(x):
    """Retourne le carre du nombre x."""
    return x ** 2

def est_pair(n):
    """Verifie si n est un nombre pair."""
    return n % 2 == 0

def saluer(nom):
    """Affiche un message de salutation personnalise."""
    print(f"Bonjour, {nom}!")

Les docstrings simples doivent :

  • Tenir sur une seule ligne (guillemets inclus)
  • Utiliser des guillemets triples meme pour une ligne
  • Ne pas avoir de ligne vide avant ou apres
  • Etre une phrase complete finissant par un point

Docstrings multi-lignes

Pour une documentation plus detaillee, utilisez des docstrings multi-lignes :

def calculer_moyenne(nombres):
    """
    Calcule la moyenne arithmetique d'une liste de nombres.

    Cette fonction prend une liste de nombres (entiers ou flottants)
    et retourne leur moyenne. La liste ne doit pas etre vide.

    Args:
        nombres: Une liste de nombres (int ou float).

    Returns:
        La moyenne des nombres sous forme de float.

    Raises:
        ValueError: Si la liste est vide.
        TypeError: Si la liste contient des elements non numeriques.
    """
    if not nombres:
        raise ValueError("La liste ne peut pas etre vide")
    return sum(nombres) / len(nombres)

Conventions PEP 257

La PEP 257 definit les conventions semantiques pour les docstrings Python. Voici les points essentiels :

Structure recommandee

def fonction_exemple(param1, param2):
    """Resume court de la fonction (une ligne).

    Description plus detaillee si necessaire. Cette section peut
    s'etendre sur plusieurs lignes et fournir des informations
    supplementaires sur le comportement de la fonction.

    Args:
        param1: Description du premier parametre.
        param2: Description du second parametre.

    Returns:
        Description de la valeur de retour.

    Raises:
        ExceptionType: Quand cette exception est levee.
    """
    pass

Documentation des modules

"""
Module de gestion des utilisateurs.

Ce module fournit des classes et fonctions pour gerer les utilisateurs
dans l'application. Il inclut la creation, modification et suppression
des comptes utilisateurs.

Exemple d'utilisation:
    from utilisateurs import Utilisateur

    user = Utilisateur("Jean", "jean@email.com")
    user.activer()

Attributs du module:
    MAX_UTILISATEURS (int): Nombre maximum d'utilisateurs autorises.
    VERSION (str): Version actuelle du module.
"""

MAX_UTILISATEURS = 1000
VERSION = "1.2.0"

Documentation des classes

class CompteBancaire:
    """
    Represente un compte bancaire avec operations de base.

    Cette classe permet de gerer un compte bancaire avec des operations
    de depot, retrait et consultation du solde. Elle inclut egalement
    un historique des transactions.

    Attributes:
        titulaire (str): Nom du titulaire du compte.
        solde (float): Solde actuel du compte.
        numero (str): Numero unique du compte.
        historique (list): Liste des transactions effectuees.

    Example:
        >>> compte = CompteBancaire("Alice", 1000.0)
        >>> compte.deposer(500)
        >>> print(compte.solde)
        1500.0
    """

    def __init__(self, titulaire, solde_initial=0.0):
        """
        Initialise un nouveau compte bancaire.

        Args:
            titulaire: Nom du titulaire du compte.
            solde_initial: Montant initial du compte (defaut: 0.0).

        Raises:
            ValueError: Si le solde initial est negatif.
        """
        if solde_initial < 0:
            raise ValueError("Le solde initial ne peut pas etre negatif")
        self.titulaire = titulaire
        self.solde = solde_initial
        self.numero = self._generer_numero()
        self.historique = []

    def deposer(self, montant):
        """
        Depose un montant sur le compte.

        Args:
            montant: Montant a deposer (doit etre positif).

        Returns:
            Le nouveau solde apres le depot.

        Raises:
            ValueError: Si le montant est negatif ou nul.
        """
        if montant <= 0:
            raise ValueError("Le montant doit etre positif")
        self.solde += montant
        self.historique.append(f"Depot: +{montant}")
        return self.solde

Formats de Docstrings populaires

Format Google Style

Le format Google est lisible et largement adopte :

def rechercher_utilisateur(nom, actif_seulement=True, limite=10):
    """Recherche des utilisateurs par nom.

    Effectue une recherche dans la base de donnees des utilisateurs
    en utilisant une correspondance partielle sur le nom.

    Args:
        nom (str): Le nom ou partie du nom a rechercher.
        actif_seulement (bool, optional): Si True, retourne uniquement
            les utilisateurs actifs. Defaults to True.
        limite (int, optional): Nombre maximum de resultats a retourner.
            Defaults to 10.

    Returns:
        list[Utilisateur]: Liste des utilisateurs correspondants,
            triee par pertinence.

    Raises:
        ValueError: Si le nom est vide ou None.
        DatabaseError: Si la connexion a la base echoue.

    Examples:
        >>> rechercher_utilisateur("Jean")
        [Utilisateur('Jean Dupont'), Utilisateur('Jean Martin')]

        >>> rechercher_utilisateur("Marie", limite=5)
        [Utilisateur('Marie Curie'), ...]
    """
    pass

Format NumPy Style

Le format NumPy est populaire dans la communaute scientifique :

def transformer_matrice(matrice, rotation=0, echelle=1.0):
    """
    Applique une transformation geometrique a une matrice.

    Parameters
    ----------
    matrice : numpy.ndarray
        Matrice 2D a transformer.
    rotation : float, optional
        Angle de rotation en degres (default: 0).
    echelle : float, optional
        Facteur d'echelle (default: 1.0).

    Returns
    -------
    numpy.ndarray
        La matrice transformee.

    Raises
    ------
    ValueError
        Si la matrice n'est pas 2D.

    See Also
    --------
    numpy.rot90 : Rotation par multiples de 90 degres.
    scipy.ndimage.rotate : Rotation arbitraire.

    Notes
    -----
    La rotation est effectuee autour du centre de la matrice.
    L'interpolation bilineaire est utilisee pour les valeurs.

    Examples
    --------
    >>> import numpy as np
    >>> m = np.array([[1, 2], [3, 4]])
    >>> transformer_matrice(m, rotation=90)
    array([[2, 4],
           [1, 3]])
    """
    pass

Format reStructuredText (Sphinx)

Format utilise par Sphinx pour la generation de documentation :

def envoyer_email(destinataire, sujet, corps, pieces_jointes=None):
    """
    Envoie un email avec pieces jointes optionnelles.

    :param destinataire: Adresse email du destinataire.
    :type destinataire: str
    :param sujet: Sujet de l'email.
    :type sujet: str
    :param corps: Corps du message (HTML ou texte).
    :type corps: str
    :param pieces_jointes: Liste des chemins vers les fichiers a joindre.
    :type pieces_jointes: list[str], optional
    :returns: True si l'email a ete envoye avec succes.
    :rtype: bool
    :raises smtplib.SMTPException: Si l'envoi echoue.

    .. note::
       Cette fonction utilise le serveur SMTP configure dans settings.py.

    .. warning::
       Les pieces jointes volumineuses peuvent ralentir l'envoi.

    Example::

        >>> envoyer_email("user@example.com", "Test", "Contenu")
        True
    """
    pass

Acceder aux Docstrings

Python offre plusieurs moyens d’acceder aux docstrings :

def exemple():
    """Ceci est une fonction exemple."""
    pass

# Methode 1: Attribut __doc__
print(exemple.__doc__)
# Output: Ceci est une fonction exemple.

# Methode 2: Fonction help()
help(exemple)
# Affiche une aide formatee

# Methode 3: Module inspect
import inspect
print(inspect.getdoc(exemple))
# Output: Ceci est une fonction exemple.

# Pour les classes
class MaClasse:
    """Documentation de la classe."""

    def methode(self):
        """Documentation de la methode."""
        pass

print(MaClasse.__doc__)
print(MaClasse.methode.__doc__)

Bonnes Pratiques

1. Soyez concis mais complet

Ecrivez des docstrings qui repondent aux questions essentielles : quoi, pourquoi, comment.

# Bien
def valider_email(email):
    """
    Valide le format d'une adresse email.

    Utilise une expression reguliere pour verifier que l'email
    respecte le format standard RFC 5322.

    Args:
        email: Chaine contenant l'adresse email a valider.

    Returns:
        True si l'email est valide, False sinon.
    """
    pass

# A eviter (trop vague)
def valider_email(email):
    """Valide un email."""
    pass

2. Documentez les effets de bord

def incrementer_compteur():
    """
    Incremente le compteur global et log l'operation.

    Note:
        Cette fonction modifie la variable globale COMPTEUR
        et ecrit une entree dans le fichier de log.
    """
    global COMPTEUR
    COMPTEUR += 1
    logger.info(f"Compteur incremente: {COMPTEUR}")

3. Incluez des exemples

def formater_telephone(numero):
    """
    Formate un numero de telephone au format francais.

    Args:
        numero: Numero de telephone (10 chiffres).

    Returns:
        Numero formate avec espaces.

    Examples:
        >>> formater_telephone("0612345678")
        '06 12 34 56 78'

        >>> formater_telephone("01 23 45 67 89")
        '01 23 45 67 89'
    """
    pass

4. Utilisez un format coherent

Choisissez un format (Google, NumPy, ou Sphinx) et utilisez-le dans tout le projet.

Pieges Courants

1. Docstrings obsoletes

Le piege le plus courant est de modifier le code sans mettre a jour la docstring :

# PROBLEME: La docstring ne correspond plus au code
def calculer_prix(quantite, prix_unitaire, reduction=0):
    """Calcule le prix total d'une commande."""  # Manque le parametre reduction!
    return quantite * prix_unitaire * (1 - reduction)

2. Repeter le code au lieu de l’expliquer

# A eviter
def get_user_by_id(user_id):
    """Retourne l'utilisateur avec l'id user_id."""  # Inutile!
    pass

# Mieux
def get_user_by_id(user_id):
    """
    Recupere un utilisateur depuis la base de donnees.

    Args:
        user_id: Identifiant unique de l'utilisateur.

    Returns:
        L'objet Utilisateur correspondant.

    Raises:
        UserNotFoundError: Si aucun utilisateur ne correspond a l'id.
    """
    pass

3. Oublier les cas limites

# Incomplet
def diviser(a, b):
    """Divise a par b."""
    pass

# Complet
def diviser(a, b):
    """
    Divise a par b.

    Args:
        a: Numerateur.
        b: Denominateur (ne doit pas etre zero).

    Returns:
        Le resultat de a/b.

    Raises:
        ZeroDivisionError: Si b est egal a zero.
    """
    pass

4. Mauvaise indentation

# INCORRECT
def exemple():
"""Cette docstring est mal indentee."""
    pass

# CORRECT
def exemple():
    """Cette docstring est correctement indentee."""
    pass

Outils de Generation de Documentation

Sphinx

Sphinx est l’outil standard pour generer une documentation HTML/PDF a partir des docstrings :

# Installation
pip install sphinx

# Initialisation
sphinx-quickstart docs

# Generation de la documentation
sphinx-apidoc -o docs/source mon_module
cd docs && make html

pydoc

Module integre a Python pour generer une documentation simple :

# Voir la documentation dans le terminal
python -m pydoc mon_module

# Generer un fichier HTML
python -m pydoc -w mon_module

# Lancer un serveur de documentation
python -m pydoc -p 8080

pdoc3

Alternative moderne et simple a Sphinx :

pip install pdoc3
pdoc --html mon_module -o docs/

Conclusion

Les docstrings sont un element fondamental de tout code Python professionnel. Elles permettent non seulement de documenter le code pour les autres developpeurs, mais aussi de generer automatiquement une documentation complete et a jour.

Les points cles a retenir sont :

  1. Utilisez toujours des docstrings pour les modules, classes, fonctions et methodes publiques
  2. Choisissez un format coherent (Google, NumPy, ou Sphinx) pour tout votre projet
  3. Documentez les parametres, retours et exceptions de maniere complete
  4. Incluez des exemples pour les fonctions complexes
  5. Maintenez les docstrings a jour lorsque le code evolue

Une bonne documentation est un investissement qui facilite la maintenance, l’integration de nouveaux developpeurs et la qualite globale du projet. En suivant les conventions PEP 257 et les bonnes pratiques presentees dans cet article, vous produirez un code Python plus professionnel et plus facile a maintenir.

Ressources Supplementaires

Advertisement

In-Article Ad

Dev Mode

Share this article

Mahmoud DEVO

Mahmoud DEVO

Senior Full-Stack Developer

I'm a passionate full-stack developer with 10+ years of experience building scalable web applications. I write about Vue.js, Node.js, PostgreSQL, and modern DevOps practices.

Enjoyed this article?

Subscribe to get more tech content delivered to your inbox.

Related Articles