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) # 42Arguments 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") # suppressedMasquage 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 FalseUn 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) # TrueImplé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
passVé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
- L’instruction with en profondeur
- Protocole __enter__ et __exit__
- contextlib : @contextmanager
- Schémas pratiques de gestionnaires de contexte