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

with : le nettoyage garanti with: guaranteed cleanup

f.close() écrit en dernière ligne d'une fonction a l'air de garantir la fermeture du fichier. Il ne le fait pas : une exception levée plus haut saute directement par-dessus cette ligne, sans jamais l'exécuter. with appelle __exit__ quoi qu'il arrive à l'intérieur du bloc — return anticipé, exception, ou sortie normale — le même contrat que finally, mais porté par l'objet lui-même. f.close() written on a function's last line looks like it guarantees the file gets closed. It doesn't: an exception raised further up jumps straight over that line, never running it. with calls __exit__ no matter what happens inside the block — early return, exception, or normal exit — the same contract as finally, but carried by the object itself.

AudienceAudience
Dev qui a vu un fichier ou une connexion rester ouverte après un crash au milieu d'une fonction Dev who's watched a file or connection stay open after a crash mid-function
Format
Self-paced
ChapitresChapters
5
Date
Juil 2026 Jul 2026
≈ 18 min ●●●○ Context managerswithExceptions

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

f.close() en dernière ligne ressemble à une garantie. Ce n'est qu'un espoir.f.close() on the last line looks like a guarantee. It's only a hope.

Le Vol. VI a fermé sur une question de mémoire ; ce volume ouvre sur une question de nettoyage. Le numéro 08 a montré que la syntaxe de Python passe par des dunders ; with n'y échappe pas — ce numéro met au travail les siens, __enter__ et __exit__. Le réflexe le plus répandu pour fermer un fichier consiste à appeler close() en dernière ligne d'une fonction. Ce réflexe suppose, à tort, que le contrôle atteindra toujours cette ligne. Toute exception levée entre l'ouverture et cette dernière ligne saute directement par-dessus elle — le fichier reste ouvert, sans qu'aucune erreur ne le signale jamais.Vol. VI closed on a question of memory; this volume opens on a question of cleanup. Issue 08 showed that Python's syntax runs through dunders; with is no exception — this issue puts its own, __enter__ and __exit__, to work. The most common reflex for closing a file is calling close() on a function's last line. That reflex wrongly assumes control will always reach that line. Any exception raised between the opening and that last line jumps straight over it — the file stays open, with no error ever signaling it.

Une exception saute directement par-dessus f.close()An exception jumps straight over f.close()
def traiter(chemin):
    f = open(chemin)
    donnees = f.read()
    resultat = 1 / len(donnees)     # lève ZeroDivisionError si le fichier est vide
    f.close()                        # cette ligne ne s'exécute JAMAIS dans ce cas
    return resultat

traiter("vide.txt")
# ZeroDivisionError -- et le fichier reste ouvert, personne n'a appelé close()
Le sous-réflexe du numéroThis issue's sub-reflex

Face à toute ressource ouverte — fichier, verrou, connexion — demande : ce nettoyage s'exécute-t-il seulement si tout se passe bien, ou même si une exception traverse le bloc ? S'il ne s'exécute que dans le premier cas, ce n'est pas une garantie.Facing any opened resource — file, lock, connection — ask: does this cleanup run only if everything goes well, or even if an exception crosses the block? If it only runs in the first case, it isn't a guarantee.

Ce n'est pas propre à open()It's not specific to open()

Le même problème touche un verrou (threading.Lock), une connexion réseau ou base de données, une transaction : toute ressource acquise puis censée être libérée par une dernière ligne de code, jamais garantie d'être atteinte.The same problem hits a lock (threading.Lock), a network or database connection, a transaction: any resource acquired and supposedly released by a final line of code, never guaranteed to be reached.

🔒

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