with garantit la libération d’une ressource même en cas d’erreur (fichiers, connexions, verrous).
objectifs
- utiliser
withavec fichiers et verrous - créer un context manager via
contextlib.contextmanager - créer un context manager via une classe
__enter__/__exit__
explication détaillée
with open(...) as f: appelle f.__enter__() au début et f.__exit__() à la fin, même si une exception survient.
contextlib.contextmanager permet d’écrire un context manager fonctionnel avec yield.
exemples exécutables
# with fichier
with open("note.txt", "w", encoding="utf-8") as f:
f.write("ok")
print("fichier fermé ? ->", f.closed)
# contextmanager fonctionnel
from contextlib import contextmanager
@contextmanager
def opened(path, mode="r", encoding="utf-8"):
f = open(path, mode, encoding=encoding)
try:
yield f
finally:
f.close()
with opened("note.txt", "r", encoding="utf-8") as f:
print(f.read())
# context manager orienté objet
class Timer:
from time import perf_counter as _now
def __enter__(self):
self.start = self._now()
return self
def __exit__(self, exc_type, exc, tb):
self.elapsed = self._now() - self.start
# laisser l'exception remonter (retourner False ou None)
return False
from time import sleep
with Timer() as t:
sleep(0.05)
print(f"elapsed ~ {t.elapsed:.3f}s")
bonnes pratiques
- utilisez
withpour toutes les ressources à fermer/libérer - centralisez la gestion des ressources communes dans un CM réutilisable
- documentez si votre CM supprime ou modifie des fichiers
pièges courants
- oublier d’utiliser
with→ fuites de descripteurs de fichiers - attraper et masquer des exceptions dans
__exit__sans les consigner - écrire un CM qui change l’état global sans le restaurer
exercices
- écrire un CM
chdir(tmp_path)qui change de dossier puis restaure. - écrire un CM
suppress(*exceptions)(hint: contextlib.suppress existe déjà). - écrire un CM
tempfile_path(suffix)qui crée un fichier temporaire et le supprime à la sortie.