Bibliothèque · Notes de lecture

Fluent Python

De Luciano Ramalho. 1 011 pages sur une seule idée : écrire du Python qui parle la même langue que l'interpréteur.

FR EN
Couverture de Fluent Python, Luciano Ramalho

Fluent Python

Fluent Python: Clear, Concise, and Effective Programming

8 /10

« Énorme, dense, exigeant : le livre qui sépare ceux qui écrivent du Python de ceux qui le parlent. »

  • AuteurLuciano Ramalho
  • Édition2e éd. 2022 · 1 011 pages
  • ÉditeurO'Reilly
  • Goodreads4,62/5 · 1 900 notes
  • Fiche~9 min de lecture
Notation du livre sur 5 dimensionsIdées9/10Applicable7/10Lisibilité7/10Actualité9/10Exemples9/10

Le livre qui transforme un dev qui écrit du Python en dev qui pense en Python.

Pourquoi ce livre

Il existe des dizaines de livres pour apprendre Python. Fluent Python n'en fait pas partie : Ramalho suppose que vous écrivez déjà du Python, et s'attaque au problème suivant. Du Python qui marche mais qui sent le Java traduit, le PHP déguisé, le JS recopié. Son angle : vous montrer comment le langage pense, pour que votre code parle la même langue que l'interpréteur.

La préface annonce la méthode : utiliser avant de construire. Vous utilisez les ABCs avant d'en écrire une, vous vivez avec les métaclasses avant d'en créer. Et une mise en garde qui donne le ton : « l'abstraction prématurée est aussi mauvaise que l'optimisation prématurée » (préface).

Les idées qui restent

1L'iceberg : le Python Data Model

Pourquoi len(obj) et pas obj.len() ? Pourquoi obj[clé] déclenche __getitem__ ? Parce que Python repose sur un contrat : les special methods (les « dunders » : __len__, __getitem__...) que l'interpréteur appelle à votre place. « L'iceberg s'appelle le Python Data Model, et c'est l'API qui permet à nos objets de bien jouer avec les fonctionnalités les plus idiomatiques du langage » (p. 3). Et pourquoi len() n'est pas une méthode ? Réponse de Raymond Hettinger rapportée dans le livre : pour les types natifs, CPython lit directement un champ de la structure C, sans appel de méthode. « Practicality beats purity. » Tout le livre découle de cette logique : le langage privilégie le pratique cohérent sur le pur théorique.

2Deux méthodes, six capacités gratuites

L'exemple d'ouverture, FrenchDeck, est un paquet de 52 cartes en 15 lignes. Il implémente seulement __len__ et __getitem__. Résultat : len(deck), deck[0], le slicing deck[12::13] (les quatre as), la boucle for, l'opérateur in et sorted() fonctionnent, sans héritage, sans interface déclarée. C'est le retour sur investissement du Data Model : implémentez le contrat, le langage fait le reste.

class FrenchDeck:
    def __len__(self):
        return len(self._cards)
    def __getitem__(self, position):
        return self._cards[position]

>>> len(deck)        # 52
>>> deck[12::13]     # les quatre as
>>> Card('Q', 'hearts') in deck   # True

3Les variables sont des étiquettes, pas des boîtes

Le piège Python le plus fréquent vient d'une image mentale fausse. « L'instruction b = a ne copie pas le contenu de la boîte a dans la boîte b. Elle attache l'étiquette b à l'objet qui porte déjà l'étiquette a » (p. 203). D'où le HauntedBus du chapitre 6 : un paramètre par défaut mutable (def __init__(self, passengers=[])) est créé une seule fois et partagé. Les passagers fantômes montés dans un bus apparaissent dans tous les bus créés sans passagers.

4Closures : la fonction emporte son environnement

make_averager() retourne une fonction qui calcule une moyenne mobile. La liste series est une variable locale de make_averager, pourtant la fonction retournée y accède bien après. C'est une closure : « une fonction qui retient les liaisons des variables libres existant quand la fonction est définie » (p. 314). Subtilité que le livre démonte : réassigner (count += 1) casse la closure, parce que l'assignation rend la variable locale. Le mot-clé nonlocal existe exactement pour ça.

5Les décorateurs et leurs deux temporalités

Un décorateur, c'est target = decorate(target), rien de plus. Mais le chapitre 9 installe une distinction qui change la lecture du code : les décorateurs s'exécutent à l'import du module, les fonctions décorées à l'appel. Et la démonstration de force : fibonacci(30) récursif naïf appelle fibonacci(1) 832 040 fois (12 secondes) ; avec @functools.cache, une ligne au-dessus de la définition, 31 appels et 0,00017 seconde.

6Duck typing, goose typing : la carte des types

Depuis Python 3.8, il y a quatre façons de penser les interfaces, que le livre cartographie sur deux axes : vérification à l'exécution ou statique, typage par structure ou par nom. Le duck typing classique (l'objet a la méthode, donc ça marche : la classe Vowels avec un seul __getitem__ est itérable), le goose typing (ABCs + isinstance), le typage statique (type hints à la Java), et le static duck typing (typing.Protocol, l'approche de Go). Le verdict du livre : ces quatre approches sont complémentaires, aucune ne mérite d'être écartée (p. 432). La carte sert à choisir en conscience : duck typing pour un script, Protocol pour une lib publique, ABCs quand il faut vérifier à l'exécution.

7yield : l'Iterator pattern intégré au langage

Quand les données ne tiennent pas en mémoire, il faut les produire une à la fois, à la demande. Là où Java implémente le design pattern Iterator à la main, Python l'a intégré : toute fonction contenant yield devient une factory de générateurs. Précision de vocabulaire que le livre martèle : une fonction retourne une valeur, un générateur yield des valeurs. La version paresseuse de la classe Sentence (via re.finditer) ne lit le mot suivant que quand on le demande.

8Le GIL, expliqué en dix points

Le chapitre 19 démine le sujet le plus mal compris de Python : un seul thread Python s'exécute à la fois, quel que soit le nombre de cœurs. Mais toutes les fonctions qui font un appel système (I/O disque, réseau, time.sleep) libèrent le GIL. Conséquence : les threads Python sont excellents pour attendre (« Python threads are great at doing nothing », David Beazley, cité p. 700) et inutiles pour le calcul. Détail peu connu listé au point 6 : beaucoup de fonctions CPU-intensives de NumPy/SciPy et les compressions zlib/bz2 libèrent aussi le GIL, c'est pour ça que le calcul scientifique en threads peut marcher. Pour du CPU intensif en Python pur : plusieurs processus.

Trois choses que je ne savais pas avant de le lire

Mon avis, honnêtement

Ce que le livre a d'unique : son fil conducteur. Les autres livres Python listent des fonctionnalités ; celui-là déroule une seule idée (le Data Model) sur cinq parties, et chaque chapitre la confirme. Les exemples portent des noms (FrenchDeck, HauntedBus) qu'on retient des années.

La critique méritée : 1 011 pages, c'est un marathon, et tout le monde ne finira pas. Les chapitres sur les type hints (8 et 15) sont arides. La partie V (métaprogrammation) concerne peut-être 5 % des lecteurs. Ramalho le sait : il a structuré le livre en « cinq livres en un », à lire par parties. Prenez-le comme un livre de chevet de six mois, pas une lecture d'une semaine.

En 2026, l'IA génère du Python qui marche, rarement du Python idiomatique : des getters/setters inutiles, des boucles indexées là où une comprehension suffit, du threading là où le GIL l'annule. Fluent Python est la grille qui permet de voir la différence entre du Python et du Java traduit en Python.

Odilon

Toujours valable en 2026 ?

Deuxième édition de 2022, Python 3.10 : pattern matching et typing moderne couverts. Le projet de GIL optionnel (PEP 703, Python 3.13+) ne change pas les dix points du chapitre 19 pour l'instant : le GIL reste activé par défaut. Les fondamentaux (Data Model, références, closures) ne bougent pas, parce qu'ils sont le langage lui-même.

Pour qui ?

Lisez-le si

  • Vous avez 1-2 ans de Python et vos programmes marchent sans que vous sachiez toujours pourquoi
  • Vous venez de Java, PHP ou JS et votre Python ressemble encore à votre ancien langage
  • Vous relisez du Python généré par IA et voulez reconnaître ce qui n'est pas idiomatique
  • Vous voulez comprendre les __dunders__ au lieu de les copier de Stack Overflow

Passez si

  • Vous débutez en programmation : Python Crash Course d'abord, celui-là dans deux ans
  • Vous cherchez des recettes à coller : c'est un livre de modèle mental, pas un cookbook
  • Vous utilisez Python occasionnellement pour des scripts : le retour sur 1 011 pages ne sera pas là

Pour aller plus loin

Les fondamentaux de ce livre se pratiquent dans le cours Python de ce site. Pour relire du code généré avec un œil critique, voyez Coder avec l'IA. L'équivalent TypeScript du rôle de ce livre est Effective TypeScript, aussi dans cette bibliothèque.

Commentaires (0)

Voir toute la bibliothèque

D'autres fiches arrivent : un livre à la fois, la substantifique moelle seulement.