5.1 · Code propre & design patterns (PEP 8, SOLID)

Niveau 5 · Niveau pro & industrialisation

5.1Code propre & design patterns (PEP 8, SOLID)

Objectif : Écrire un code lisible, structuré et maintenable.
Temps estimé : 14 min · lecture autonome · Si vous n'avez que 5 min : lisez « L'essentiel en 30s » + le schéma.

L'essentiel en 30 secondes

  • PEP 8 automatisée : nommage et mise en forme prévisibles — black/ruff tranchent, on ne débat plus du style en revue.
  • SOLID pragmatique : une responsabilité par unité, dépendre d'abstractions — sans dogme sur les petits scripts.
  • Patterns nommés : Fabrique, Stratégie, Adaptateur, Contexte — un nom vaut dix phrases d'explication.

Mini-cas filé — Nabil range ses scripts à Alger

Nabil, data analyst junior à Alger, jongle avec des scripts d'analyse qui « marchent » mais que personne ne relit sans grimacer : noms cryptiques, fonction géante qui charge, nettoie, calcule et affiche, style différent à chaque fichier. Il passe black/ruff, renomme en explicite et découpe la fonction géante en unités à responsabilité unique. Cette section raconte son passage au code pro — et le fil continue en 5.2, 5.3 et 5.4.

Ce même cas revient dans le cours, le schéma, le script et le défi 48h — et continue en 5.2, 5.3 et 5.4.

1. PEP 8 : la grammaire commune

Au niveau pro, le code se relit plus qu'il ne s'écrit. La PEP 8 est le guide de style officiel de Python : snake_case pour les fonctions, PascalCase pour les classes, UPPER pour les constantes, lignes contenues, deux lignes entre fonctions. La suivre rend tout code prévisible : un lecteur sait où regarder. Nabil cesse de réinventer son style à chaque script — il adopte la grammaire commune.

Le point décisif : le style s'automatise. black reformate, ruff (ou flake8/pylint) signale les écarts — le style ne se débat plus en revue, l'outil tranche. On installe, on lance avant chaque commit, on corrige ce qui est signalé.

2. SOLID en pratique (sans dogme)

SOLID guide la découpe : une seule responsabilité par fonction ou classe, ouvert à l'extension (paramètres, plugins) mais fermé à la modification (ajouter sans casser), dépendre d'abstractions plutôt que de détails concrets — en Python, le duck typing aide (« si ça cancane, c'est un canard »). Nabil découpe sa fonction géante : une fonction charge, une autre nettoie, une troisième calcule — chacune testable.

Mais le pragmatisme prime : un petit script jetable n'a pas besoin d'une usine abstraite. On structure ce qui grandit et dure, on laisse simple ce qui est ponctuel. Le god-object qui fait tout et l'usine à gaz pour cinquante lignes sont les deux bords à éviter.

3. Les patterns qui paient

Les design patterns sont des solutions éprouvées à des problèmes de conception récurrents. Ceux qui paient vite en Python : la Fabrique (créer l'objet selon la config), la Stratégie (algorithmes interchangeables — le dictionnaire de fonctions de l'exemple), l'Adaptateur (unifier des API différentes derrière une même interface), le Contexte (un with maison via contextlib pour gérer proprement les ressources). Nabil remplace sa cascade de elif par une stratégie nommée : ajouter un mode devient ajouter une entrée.

Bonus d'équipe : un pattern nommé dans une revue vaut dix phrases d'explication — « c'est une stratégie » dit tout. On les découvre au fil des besoins, jamais par cœur d'un coup.

Erreur d'interprétation fréquente : « Pour être pro, il faut appliquer SOLID à la lettre et des patterns partout ». Non. Sans problème de conception, le pattern est du poids mort ; sans croissance du code, l'architecture est de la paperasse. Le bon réflexe : partir de la douleur (fonction intestable, duplication, elif qui s'allonge), puis choisir l'outil minimal — jamais l'inverse.
Code qui se relit Prévisible et testable PEP 8 (auto)Style commun, black/ruff tranchent+SOLID (pragmatique)Une responsabilité par unité+Patterns (nommés)Stratégie, Fabrique, Adaptateur Le style ne se débat plus en revue : l'outil tranche avant le commit.
Prévisible et testable
Version texte du schéma (SEO / lecteurs d'écran / traduction) : 1) PEP 8 : Nabil passe ses scripts d'analyse à Alger sous black/ruff — nommage explicite, mise en forme uniforme. 2) SOLID : il découpe sa fonction géante (une responsabilité par unité) et dépend d'abstractions. 3) Patterns : il remplace la cascade de elif par une stratégie nommée — ajouter un mode devient ajouter une entrée. Leçon : prévisible et testable, avec mesure.

🔎 Exemple concret — Nabil remplace ses elif par une stratégie

Avant/après black + stratégie nommée.

# AVANT : rigide
def calculer(mode, x):
    if mode == "tva":
        return x * 1.2
    elif mode == "remise":
        return x * 0.9

# APRES : strategie nommee
STRATEGIES = {"tva": lambda x: x * 1.2, "remise": lambda x: x * 0.9}


def calculer(mode, x):
    return STRATEGIES[mode](x)

Lecture : ajouter un mode = une entrée dans le dictionnaire, pas un elif de plus.

Leçon : black . + ruff check . avant chaque commit.

Vocabulaire de la section

PEP 8
Le guide de style officiel de Python, qui rend tout code prévisible.

Exemple simple : Nabil renomme ses variables en snake_case explicite.

Ce que ce n'est pas : un outil qui accélère l'exécution.

Réflexe : un inconnu lirait-il mon code sans effort ?

Code propre
Code lisible : noms explicites, fonctions courtes, zéro duplication.

Exemple simple : Nabil découpe sa fonction géante en trois unités testables.

Ce que ce n'est pas : du code qui marche mais qu'on n'ose pas relire.

Réflexe : chaque fonction a-t-elle une seule responsabilité ?

black / ruff
Outils qui formatent (black) et contrôlent le style (ruff) automatiquement.

Exemple simple : Nabil lance black puis ruff avant chaque commit.

Ce que ce n'est pas : un débat de style à la main en revue.

Réflexe : l'outil a-t-il tranché avant la revue ?

SOLID
Principes de découpe vers un code découplé et maintenable, à appliquer sans dogme.

Exemple simple : Nabil ouvre à l'extension par paramètres au lieu de modifier.

Ce que ce n'est pas : une check-list à cocher aveuglément.

Réflexe : cette structure paie-t-elle son coût ?

Stratégie
Pattern : des algorithmes interchangeables derrière une même interface.

Exemple simple : Les modes de calcul de Nabil deviennent des entrées du dictionnaire.

Ce que ce n'est pas : une cascade de elif qui s'allonge.

Réflexe : puis-je ajouter un cas sans toucher l'existant ?

En pratique — Rendre son code propre et conforme

  1. Reprenez un ancien script et renommez ses variables/fonctions de façon explicite (snake_case, noms parlants).
  2. Installez black (pip install black) et lancez-le sur le fichier : observez la mise en forme automatique et uniforme.
  3. Installez flake8 et corrigez les avertissements de style qu'il signale.
  4. Découpez une fonction trop longue en plusieurs fonctions courtes à responsabilité unique : mesurez le gain de lisibilité.
Votre code respecte PEP 8, est reformaté par black et validé par flake8 : il devient lisible, cohérent et professionnel.

Script prêt à dire — proposer le style auto

« À Alger, nos scripts d'analyse marchent mais se relisent mal : styles différents, noms cryptiques, fonctions géantes. Je propose qu'on fige PEP 8 avec black et ruff avant chaque commit, et qu'on découpe la fonction la plus douloureuse en unités à responsabilité unique. On mesure le gain en relecture, puis on étend. »

À dire en revue pour faire adopter le formatage auto sans promettre une réécriture complète.

Modèle copier-coller — check-list relecture propre

RELECTURE CODE PROPRE (1 fichier)
NOMMAGE : snake_case fonctions / PascalCase classes / UPPER constantes ? ___
DECOUPE : chaque fonction a-t-elle UNE seule responsabilite ? -> A decouper : ___
DUPLICATION : meme logique a 2 endroits ? -> A factoriser : ___
OUTILS : black passe ? ___ · ruff check propre ? ___
PATTERN : un elif qui s'allonge -> strategie envisageable ? ___

Solo / petit budget

Nabil seul : black + renommage explicite sur le script le plus relu suffit — pas de réécriture complète.

TPE / équipe réduite

Un pre-commit black/ruff partagé : toute l'équipe produit le même style sans en discuter.

PME à Alger

Nabil cale une relecture mensuelle à Alger : une fonction géante découpée à chaque fois, patterns nommés en revue.

Équipe qui démarre

Binôme : l'un code, l'autre relit avec la check-list ; on n'ajoute un pattern que sur douleur réelle.

✓ Bonnes pratiques

  • black/ruff en pre-commit : le style est tranché par l'outil.
  • Une responsabilité par unité : découper la fonction la plus douloureuse d'abord.
  • Nommer les patterns en revue : un nom partagé vaut dix phrases.

✗ Pièges fréquents

  • Débattre du style à la main au lieu d'automatiser.
  • Monter une usine à gaz pour cinquante lignes.
  • Laisser un god-object qui fait tout (charger, nettoyer, calculer, afficher).

Points clés à retenir

  • PEP 8 est le style officiel de Python : le suivre rend le code familier à tous.
  • Code propre = noms explicites + fonctions courtes + zéro duplication.
  • black reformate automatiquement ; flake8/pylint détectent les défauts.
  • Les design patterns sont des solutions éprouvées aux problèmes de conception récurrents.

Défi 48h — appliquez demain

Passez 1 script de Nabil sous black + ruff, renommez 5 noms cryptiques et découpez 1 fonction géante : la relecture est-elle plus rapide ?

Checklist sortie de section
  • Je peux expliquer PEP 8 et le rôle de black/ruff en une phrase.
  • Mon script est reformaté et sans avertissement bloquant.
  • Je sais quand NE PAS ajouter de pattern.
Auto-évaluation 1-5 : un collègue comprend-il mon code sans explication ?ai-je structuré seulement là où ça soulage ?

Questions fréquentes

Le style du code a-t-il vraiment de l'importance si ça fonctionne ?

Oui, énormément. Un code est lu bien plus souvent qu'il n'est écrit. Un style cohérent réduit les bugs, accélère la relecture et facilite le travail en équipe. C'est un critère majeur en entreprise : un code propre est un code professionnel. Et avec black/ruff, ce style ne coûte presque rien : l'outil le garantit avant chaque commit.

Faut-il apprendre tous les design patterns ?

Non, surtout pas par cœur. Comprenez d'abord les principes du code propre. Découvrez les patterns au fil des besoins : quand un problème de conception revient, il existe souvent un pattern qui le résout élégamment. Les connaître de nom aide à reconnaître ces situations — Fabrique, Stratégie, Adaptateur et Contexte couvrent déjà l'essentiel du quotidien Python.

Vérifiez votre compréhension

Que définit la convention PEP 8 ?

Ressources supplémentaires (optionnel, pour aller plus loin)

Examen du niveau 5Questions inédites et durcies pour valider vos acquis