🐍 PyTutos

Les context managers (le mot-clé with)

Gère proprement l'ouverture/fermeture de ressources avec with.

⏱ 10 minutes 📂 avance #avance #with #context-manager #ressources

Les context managers

Un context manager est un objet qui gère l'entrée et la sortie d'un bloc de code. C'est ce qui permet le fameux with open(...) as f:.

Le problème qu'ils résolvent

Sans with :

f = open("data.txt")
data = f.read()
# Si quelque chose plante ICI, le fichier n'est jamais fermé ❌
f.close()

Avec with :

with open("data.txt") as f:
    data = f.read()
# Fichier fermé automatiquement ✅ même si une exception est levée

Créer son propre context manager (classe)

Il faut deux méthodes : __enter__ et __exit__.

class Chronometre:
    def __enter__(self):
        import time
        self.debut = time.time()
        return self     # ← valeur reçue par "as ..."

    def __exit__(self, type_erreur, valeur, trace):
        import time
        duree = time.time() - self.debut
        print(f"⏱ Bloc exécuté en {duree:.2f}s")
        # Si on renvoie True, l'erreur est étouffée. Sinon elle remonte.
        return False


with Chronometre() as chrono:
    somme = sum(range(1_000_000))

# ⏱ Bloc exécuté en 0.05s

Version courte avec contextlib

contextlib.contextmanager permet d'écrire ça avec un générateur :

from contextlib import contextmanager
import time

@contextmanager
def chronometre():
    debut = time.time()
    try:
        yield     # ← le code dans le with s'exécute ici
    finally:
        print(f"⏱ {time.time()-debut:.2f}s")


with chronometre():
    sum(range(1_000_000))

Le try / finally garantit le print même en cas d'erreur.

Imbriquer plusieurs with

with open("entree.txt") as src, open("sortie.txt", "w") as dst:
    for ligne in src:
        dst.write(ligne.upper())

Cas réels

  • Fichiers : open(...)
  • Connexions BDD : sqlite3.connect(...)
  • Verrous (threading) : lock
  • Sessions HTTP : requests.Session()
  • Décorateurs de tests (mock, etc.)

💡 Dès que tu vois "il faut ouvrir et fermer quelque chose", pense with. C'est plus court, plus sûr, plus pythonique.

🧪 Quiz de validation

Réponds à toutes les questions. Il faut 70% de bonnes réponses pour valider le tuto !

🔒 Tu dois être connecté pour passer le quiz.