Table of Contents
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 :
- Utilisez toujours des docstrings pour les modules, classes, fonctions et methodes publiques
- Choisissez un format coherent (Google, NumPy, ou Sphinx) pour tout votre projet
- Documentez les parametres, retours et exceptions de maniere complete
- Incluez des exemples pour les fonctions complexes
- 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
In-Article Ad
Dev Mode
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
Maitriser les Docstrings en Python : Guide Complet pour une Documentation Efficace
Apprenez a documenter vos programmes Python avec les docstrings. Decouvrez les conventions PEP 257, les styles Google et Sphinx, et les meilleures pratiques pour creer une documentation claire et maintenable.
Recherche de valeurs dans les listes, tuples et dictionnaires Python
Apprenez a rechercher des elements dans les sequences Python : methode index(), mot-cle in, recherche dans les dictionnaires et algorithme bisect pour listes triees.
Expressions Regulieres en Python : Guide Complet pour Maitriser le Module re
Apprenez a maitriser les expressions regulieres en Python avec le module re. Decouvrez comment extraire des donnees, valider des formats, manipuler des chaines et eviter les pieges courants avec des exemples pratiques.