0Pricing
Python Academy · Leçon

Protocole __enter__ et __exit__

Créez des gestionnaires de contexte avec le protocole spécial correspondant.

Protocole __enter__ et __exit__ est une leçon Python Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Python Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Python Academy comprend 4 leçons au total.

Le protocole des gestionnaires de contexte

Tout objet qui définit __enter__ et __exit__ est un gestionnaire de contexte et peut être utilisé avec with.

class Managed:
    def __enter__(self):
        print("entering")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exiting")
        return False

with Managed() as m:
    print("inside")

Valeur renvoyée par __enter__

__enter__ est appelé au début du bloc with. Sa valeur de retour est attribuée à la variable qui suit as.

class Resource:
    def __enter__(self):
        self.value = 42
        return self  # bound to 'r'

    def __exit__(self, *args):
        self.value = None
        return False

with Resource() as r:
    print(r.value)  # 42

Arguments de __exit__

__exit__(exc_type, exc_val, exc_tb) reçoit les informations sur l’exception si une erreur s’est produite. En l’absence d’exception, les trois valeurs sont None.

class Safe:
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is ValueError:
            print(f"Suppressed ValueError: {exc_val}")
            return True   # suppress the exception
        return False      # re-raise anything else

with Safe():
    raise ValueError("oops")  # suppressed

Masquage des exceptions

Renvoyez True depuis __exit__ pour masquer l’exception. Renvoyez False (ou ne renvoyez rien) pour la laisser se propager.

class Ignore:
    def __enter__(self): return self
    def __exit__(self, *args): return True  # swallow all exceptions

with Ignore():
    1 / 0

print("continues here")

Exemple de connexion à une base de données

Cas d’usage classique : acquérir une connexion à l’entrée, valider ou annuler les changements, puis fermer la connexion à la sortie.

class DBConn:
    def __enter__(self):
        self.conn = connect_db()
        return self.conn

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            self.conn.rollback()
        else:
            self.conn.commit()
        self.conn.close()
        return False

Un gestionnaire de contexte Timer

Mesurez le temps écoulé en enregistrant le début dans __enter__ et en calculant la différence dans __exit__.

import time

class Timer:
    def __enter__(self):
        self.start = time.perf_counter()
        return self

    def __exit__(self, *args):
        self.elapsed = time.perf_counter() - self.start
        print(f"Elapsed: {self.elapsed:.3f}s")
        return False

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

Imbrication des gestionnaires de contexte

Plusieurs gestionnaires de contexte peuvent être combinés sur une seule ligne with.

with open("in.txt") as src, open("out.txt", "w") as dst:
    dst.write(src.read())

Gestionnaires réutilisables ou à usage unique

Les gestionnaires de contexte dont __enter__ alloue une nouvelle ressource à chaque utilisation sont réutilisables. Ceux qui épuisent un état interne (comme un verrou qui n’est détenu qu’une seule fois) peuvent ne pas l’être.

class Reusable:
    def __enter__(self):
        return []
    def __exit__(self, *a):
        return False

for _ in range(3):
    with Reusable() as lst:
        lst.append(1)
        print(lst)  # [1] each time

__aenter__ et __aexit__ (asynchrone)

Pour les gestionnaires de contexte asynchrones, définissez les coroutines __aenter__ et __aexit__, puis utilisez async with.

class AsyncDB:
    async def __aenter__(self):
        self.conn = await connect()
        return self.conn

    async def __aexit__(self, *args):
        await self.conn.close()

# async with AsyncDB() as conn:
#     ...

Envelopper des objets fichier

Les objets fichier de Python implémentent déjà le protocole des gestionnaires de contexte : n’appelez jamais f.close() manuellement.

with open("data.txt", "r") as f:
    data = f.read()
# file is closed here automatically
print(f.closed)  # True

Implémenter un verrou

Les verrous de threads sont des gestionnaires de contexte : __enter__ acquiert le verrou et __exit__ le libère.

import threading

lock = threading.Lock()

def update_shared():
    with lock:
        # critical section
        pass

Vérification rapide

Que doit renvoyer __exit__ pour supprimer une exception ?

Récapitulatif

Implémentez __enter__ et __exit__ pour créer des gestionnaires de contexte. Renvoyez la ressource depuis __enter__, puis gérez le nettoyage et la suppression des exceptions dans __exit__.

Questions Fréquemment Posées

La leçon « Protocole __enter__ et __exit__ » est-elle gratuite ?

Oui — le texte complet de « Protocole __enter__ et __exit__ » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Python Academy, passe à CoddyKit PRO. Le cours Python Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Protocole __enter__ et __exit__ » ?

Créez des gestionnaires de contexte avec le protocole spécial correspondant. Tu pratiques Python Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Python Academy ?

Aucune expérience préalable n'est requise. Python Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Protocole __enter__ et __exit__ » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Python Academy ?

Oui. Chaque leçon Python Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. L’instruction with en profondeur
  2. Protocole __enter__ et __exit__
  3. contextlib : @contextmanager
  4. Schémas pratiques de gestionnaires de contexte
← Retour à Python Academy