# Ceci est un commentaire, Python l'ignore
x = 10 # commentaire en fin de ligne21 Les docstrings
Un code qui fonctionne est un bon début ; un code compréhensible par un collègue (ou par vous-même dans 6 mois) est bien mieux. Les docstrings sont l’outil Python standard pour documenter vos fonctions, modules et classes. Ce chapitre est court mais essentiel : le TOSA teste les docstrings au niveau Opérationnel et Avancé.
21.1 Les commentaires (#) — rappel
Les commentaires (#) sont ignorés par l’interpréteur. Ils expliquent un choix dans le code.
Règle : un bon commentaire explique le POURQUOI, pas le QUOI. Le code dit déjà ce qu’il fait ; le commentaire doit apporter un contexte non évident.
# ❌ Inutile : redit ce que fait le code
x = x + 1 # ajoute 1 à x
# ✅ Utile : explique une décision non évidente
x = x + 1 # on compense l'indice qui commence à 0 côté base de données21.2 Les docstrings
Une docstring (documentation string) est une chaîne de documentation placée :
- Juste après la signature d’une fonction, d’une classe ou d’un module.
- Entre triples guillemets
"""...""".
def moyenne(notes):
"""Calcule la moyenne d'une liste de notes."""
return sum(notes) / len(notes)
print(moyenne([12, 15, 14]))13.666666666666666
Contrairement à un commentaire #, la docstring :
- Est associée à l’objet (fonction, classe…).
- Est accessible à l’exécution via
__doc__ouhelp(). - Est affichée par les outils de documentation (Sphinx, IDE, etc.).
Accéder à une docstring
Deux façons :
def moyenne(notes):
"""Calcule la moyenne d'une liste de notes."""
return sum(notes) / len(notes)
# Méthode 1 : attribut __doc__
print(moyenne.__doc__)Calcule la moyenne d'une liste de notes.
La seconde méthode est help() (à utiliser dans l’interpréteur interactif) :
help(moyenne)
# Help on function moyenne in module __main__:
#
# moyenne(notes)
# Calcule la moyenne d'une liste de notes.help() est particulièrement pratique dans l’interpréteur interactif : tapez help(print) pour voir l’aide d’une fonction native.
Docstring courte (une ligne)
Pour des fonctions simples :
def carre(x):
"""Renvoie le carré de x."""
return x * x
print(carre.__doc__)Renvoie le carré de x.
Convention : commencer par un verbe d’action (Renvoie, Calcule, Affiche…) et terminer par un point.
Docstring longue (multi-lignes)
Pour des fonctions plus complexes, on structure la docstring :
def statistiques(notes):
"""Calcule min, max et moyenne d'une liste de notes.
Arguments:
notes: liste de nombres (entiers ou flottants).
Renvoie:
Un tuple (minimum, maximum, moyenne).
Exemple:
>>> statistiques([12, 15, 9])
(9, 15, 12.0)
"""
return min(notes), max(notes), sum(notes) / len(notes)
print(statistiques.__doc__)Calcule min, max et moyenne d'une liste de notes.
Arguments:
notes: liste de nombres (entiers ou flottants).
Renvoie:
Un tuple (minimum, maximum, moyenne).
Exemple:
>>> statistiques([12, 15, 9])
(9, 15, 12.0)
La structure :
- Première ligne : résumé en une phrase.
- Ligne vide.
- Paragraphe(s) détaillés : arguments, retour, exemples, exceptions.
Il existe plusieurs styles de docstrings :
Google (lisible, populaire) :
Args: nom: description Returns: descriptionNumPy (utilisé en data science) :
Parameters ---------- nom : type descriptionreStructuredText / Sphinx (plus formel, plus ancien).
Choisissez-en un et tenez-vous y dans un projet. Le TOSA ne teste pas un style précis, mais la présence et la qualité des docstrings.
21.3 Les annotations de type (type hints)
Python 3 permet d’annoter les paramètres et le retour d’une fonction avec leur type attendu. C’est optionnel mais très utile.
def moyenne(notes: list) -> float:
"""Calcule la moyenne d'une liste de notes."""
return sum(notes) / len(notes)
print(moyenne([12, 15, 14]))13.666666666666666
Syntaxe :
param: type→ type attendu pour le paramètre.-> typeaprès la signature → type du retour.
Exemples d’annotations
def saluer(nom: str, age: int) -> str:
"""Renvoie un message de salutation."""
return f"Bonjour {nom}, vous avez {age} ans."
print(saluer("Alice", 30))Bonjour Alice, vous avez 30 ans.
def additionner(a: float, b: float) -> float:
return a + b
print(additionner(3.5, 2.7))6.2
Les types hints sont des indications, pas des contraintes
Les annotations sont informatives. Python ne plante pas si on passe un mauvais type :
def additionner(a: int, b: int) -> int:
return a + b
print(additionner("abc", "def")) # pas d'erreur ! concaténation de strabcdef
Pour une vraie vérification, il faut un outil externe comme mypy (vu en Partie 4).
Les annotations servent surtout :
- De documentation (plus précise qu’un commentaire).
- D’aide à l’IDE (autocomplétion, détection d’erreurs à l’écriture).
- Pour les outils de vérification statique (
mypy).
Python 3.10 — syntaxe union avec |
Depuis Python 3.10, on peut écrire int | str pour « int OU str » :
def formater(valeur: int | float | str) -> str:
"""Convertit toute valeur numérique ou textuelle en chaîne."""
return f"Valeur : {valeur}"
print(formater(42))
print(formater(3.14))
print(formater("bonjour"))Valeur : 42
Valeur : 3.14
Valeur : bonjour
Avant Python 3.10, il fallait écrire Union[int, float, str] en important typing.Union.
21.4 Bonnes pratiques de nommage (PEP 8 résumé)
La PEP 8 est la norme de style Python. Résumé :
| Élément | Style | Exemple |
|---|---|---|
| Variable, fonction | snake_case |
calculer_moyenne |
| Classe | PascalCase |
Utilisateur |
| Constante | SCREAMING_SNAKE |
TAUX_TVA = 0.20 |
| Module | snake_case |
mon_module.py |
| Privé (convention) | _underscore |
_interne |
# ✅ Conforme PEP 8
TAUX_TVA = 0.20
def calculer_prix_ttc(prix_ht):
return prix_ht * (1 + TAUX_TVA)
class Produit:
def __init__(self, nom, prix):
self.nom = nom
self.prix = prix
self._reference_interne = None # privé (convention)21.5 Le principe DRY (Don’t Repeat Yourself)
« Don’t Repeat Yourself » (ne vous répétez pas) est un principe fondamental :
Chaque morceau de logique doit exister en un seul endroit dans votre code.
# ❌ Violation DRY : on répète "taux_tva = 0.20"
def prix_ttc_pain(prix_ht):
return prix_ht * 1.20
def prix_ttc_lait(prix_ht):
return prix_ht * 1.20
def prix_ttc_fromage(prix_ht):
return prix_ht * 1.20# ✅ Respect DRY : une fonction, une constante
TAUX_TVA = 0.20
def prix_ttc(prix_ht, taux=TAUX_TVA):
return prix_ht * (1 + taux)
print(prix_ttc(10))
print(prix_ttc(5.50))12.0
6.6
Si la TVA change, on modifie une seule ligne. C’est aussi l’argument principal pour créer une fonction dès qu’on écrit deux fois le même code.
🧩 Quiz 2.1 — Documentation
Question 1
Comment accède-t-on à la docstring d’une fonction f ?
f.docf.__doc__docstring(f)help.doc(f)
b) f.__doc__ — attribut spécial de tout objet documenté. La fonction help(f) fait la même chose de façon plus lisible.
def f():
"""Exemple de docstring."""
pass
print(f.__doc__)Exemple de docstring.
Question 2
Quelle est la syntaxe correcte d’une docstring ?
# Ceci est une docstring<docstring>Ceci est une docstring</docstring>"""Ceci est une docstring."""/* Ceci est une docstring */
c) """Ceci est une docstring.""" — triple guillemets (ou triple apostrophes '''...'''), placée juste après la signature.
Question 3
Que fait Python avec les annotations de type ?
- Il vérifie les types à l’exécution et lève une erreur si faux
- Il les ignore à l’exécution (purement informatives)
- Il convertit automatiquement les arguments au bon type
- Il refuse d’exécuter le code si un type ne correspond pas
b) Il les ignore — les annotations sont purement informatives pour Python lui-même. Seuls des outils externes comme mypy les exploitent pour vérifier.
def f(x: int) -> int:
return x * 2
print(f("abc")) # pas d'erreur, Python ne vérifie pasabcabc
Question 4
Quel nom respecte la PEP 8 pour une fonction ?
CalculerMoyennecalculerMoyennecalculer_moyenneCALCULER_MOYENNE
c) calculer_moyenne — PEP 8 impose snake_case pour les fonctions et variables. Les autres styles correspondent à : PascalCase (classes), camelCase (autres langages), SCREAMING_SNAKE (constantes).
Question 5
Que signifie « DRY » ?
- Code sec et sans erreur
- Don’t Repeat Yourself — ne pas se répéter
- Dynamic Runtime Yield
- Do Reuse Yield
b) Don’t Repeat Yourself — principe qui recommande de ne pas dupliquer de logique. Dès qu’on écrit deux fois le même code, il y a un motif à extraire en fonction ou en constante.
Question 6
Où placer la docstring d’une fonction ?
- Avant le
def, en commentaire# - Juste après le
def, indentée dans le bloc de la fonction - À la fin de la fonction
- Dans un fichier séparé
b) Juste après le def — c’est la première instruction indentée du bloc. Python la reconnaît automatiquement comme __doc__.
def f(x):
"""Docstring placée correctement."""
return x * 2
print(f.__doc__)Docstring placée correctement.
✏️ Exercice 2.1 — Documenter une fonction existante
Reprenez la fonction suivante et ajoutez-y :
- Une docstring multi-lignes décrivant son but, ses arguments et son retour.
- Des annotations de type.
def prix_ttc(prix_ht, taux):
return prix_ht * (1 + taux)def prix_ttc(prix_ht, taux):
return prix_ht * (1 + taux)
# Ajoutez la docstring et les annotationsdef prix_ttc(prix_ht: float, taux: float = 0.20) -> float:
"""Calcule le prix TTC à partir d'un prix HT et d'un taux de TVA.
Arguments:
prix_ht: prix hors taxes en euros.
taux: taux de TVA (par défaut 0.20 pour 20 %).
Renvoie:
Le prix TTC correspondant (float).
Exemple:
>>> prix_ttc(100)
120.0
>>> prix_ttc(100, taux=0.055)
105.5
"""
return prix_ht * (1 + taux)
# Vérification
print(prix_ttc(100))
print(prix_ttc.__doc__)120.0
Calcule le prix TTC à partir d'un prix HT et d'un taux de TVA.
Arguments:
prix_ht: prix hors taxes en euros.
taux: taux de TVA (par défaut 0.20 pour 20 %).
Renvoie:
Le prix TTC correspondant (float).
Exemple:
>>> prix_ttc(100)
120.0
>>> prix_ttc(100, taux=0.055)
105.5
✏️ Exercice 2.2 — Module documenté
Écrivez une fonction resumer(texte, nb_mots=20) qui renvoie les nb_mots premiers mots d’un texte, suivis de "..." si le texte est plus long. Documentez-la avec une docstring complète et des annotations de type.
def resumer(texte, nb_mots=20):
...
# Tester
print(resumer("Python est un langage de programmation puissant et populaire dans le monde entier.", nb_mots=5))def resumer(texte: str, nb_mots: int = 20) -> str:
"""Renvoie les premiers mots d'un texte, tronqué si nécessaire.
Arguments:
texte: chaîne de caractères à résumer.
nb_mots: nombre maximum de mots à garder (défaut 20).
Renvoie:
Une chaîne contenant au maximum nb_mots mots, suivie de "..."
si le texte original était plus long.
Exemple:
>>> resumer("Python est un langage puissant.", nb_mots=3)
'Python est un...'
"""
mots = texte.split()
if len(mots) <= nb_mots:
return texte
return " ".join(mots[:nb_mots]) + "..."
# Tests
print(resumer("Python est un langage puissant.", nb_mots=3))
print(resumer("Bonjour", nb_mots=5))
print(resumer("Python est un langage de programmation puissant et populaire dans le monde entier.", nb_mots=5))Python est un...
Bonjour
Python est un langage de...
À retenir
- Commentaire
#: explique le pourquoi, ignoré par l’interpréteur. - Docstring
"""...""": documentation attachée à l’objet, accessible via__doc__ethelp(). - Placée juste après
def,class, ou en tête de module. - Annotations de type :
def f(x: int) -> int:— informatives, non vérifiées à l’exécution. - Python 3.10+ : syntaxe
int | strpour les unions. - PEP 8 :
snake_case(fonctions, variables),PascalCase(classes),SCREAMING_SNAKE(constantes). - Principe DRY : ne jamais dupliquer de logique — extraire en fonction ou constante.
← Chapitre précédent : Les fonctions • Chapitre suivant : Les f-strings →