Vol. 4 — № 10
The Python Loop · KiosqueNewsstand
Blog  
Un atelier Python · Édition d'ApprentissageA Python Workshop · Learning Edition

L'itérateur : __iter__, __next__, StopIteration The iterator: __iter__, __next__, StopIteration

for x in y n'est pas une primitive du langage : c'est iter(y) puis next() en boucle jusqu'à StopIteration. Cette désucre cache une distinction que la plupart des devs ne font jamais — un itérable et un itérateur ne sont pas la même chose. L'un se reparcourt à volonté ; l'autre s'épuise, une fois, et ne le dit à personne. for x in y isn't a language primitive: it's iter(y) then next() in a loop until StopIteration. That desugaring hides a distinction most devs never make — an iterable and an iterator aren't the same thing. One can be walked again and again; the other gets exhausted, once, and tells no one.

AudienceAudience
Dev qui a déjà vu une deuxième boucle for tourner à vide sans comprendre pourquoi Dev who's seen a second for loop run empty without understanding why
Format
Self-paced
ChapitresChapters
5
Date
Juil 2026 Jul 2026
≈ 18 min ●●○○ ItérateursData modelfor

Chapitre 1 en accès libre — la suite (ch. 2 à 5) est réservée. Chapter 1 free to read — the rest (ch. 2–5) is members-only.

01CadrageFraming3 min

for n'est pas une boucle native — c'est un while qui attrape une exception.for isn't a native loop — it's a while catching an exception.

Le Vol. III a posé le principe : la syntaxe désucre en dunders, cherchés sur le type. Ce volume applique ce même principe à un axe qu'on n'avait pas encore touché — le temps. for x in y appelle d'abord y.__iter__() pour obtenir un itérateur, puis appelle __next__() sur ce résultat, encore et encore, jusqu'à ce qu'il lève StopIteration. Cette exception n'est pas une erreur : c'est le signal normal, attendu, de fin de parcours. La boucle for n'est qu'une façade élégante sur ce protocole en deux temps — obtenir un itérateur, puis le tirer jusqu'à épuisement.Vol. III established the principle: syntax desugars into dunders, looked up on the type. This volume applies that same principle to an axis we hadn't touched yet — time. for x in y first calls y.__iter__() to get an iterator, then calls __next__() on that result, again and again, until it raises StopIteration. That exception isn't an error: it's the normal, expected signal that the walk is done. The for loop is just an elegant façade over this two-step protocol — get an iterator, then pull it until exhausted.

Le for désucré en toutes lettresThe for loop desugared in full
for x in y:
    corps(x)

# désucré :
it = iter(y)            # y.__iter__()  -> obtient un itérateur
while True:
    try:
        x = next(it)    # it.__next__() -> une valeur, ou lève StopIteration
    except StopIteration:
        break            # la boucle s'arrête PROPREMENT sur cette exception
    corps(x)
Le sous-réflexe du numéroThis issue's sub-reflex

Chaque fois que tu écris for, demande : l'objet que je parcours produit-il un itérateur frais à chaque appel de iter(), ou EST-il déjà l'itérateur ? La réponse change tout pour un second passage.Every time you write for, ask: does the object I'm walking produce a fresh iterator on each call to iter(), or IS it already the iterator? The answer changes everything for a second pass.

StopIteration n'est pas un échecStopIteration isn't a failure

C'est le cas le plus visible en Python où une exception sert de mécanisme de contrôle normal, pas d'erreur — le for l'attrape en silence et s'arrête. Laisser StopIteration s'échapper ailleurs que d'un __next__ est en revanche une faute : dans un générateur, depuis Python 3.7 (PEP 479), elle est convertie en RuntimeError.It's the most visible case in Python where an exception serves as a normal control mechanism, not an error — for catches it silently and stops. Letting StopIteration escape from anywhere but a __next__ is however a mistake: inside a generator, since Python 3.7 (PEP 479), it is converted into a RuntimeError.

🔒

La suite est réservée The rest is members-only

Le premier numéro est libre. Débloque tout The Python Loop — tous les volumes, à vie — pour 5 €, paiement unique. The first issue is free. Unlock all of The Python Loop — every volume, forever — for €5, one-time.

Retour au kiosqueBack to newsstand