Protocolo __enter__ y __exit__
Cree gestores de contexto mediante el protocolo dunder.
Protocolo __enter__ y __exit__ es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Python Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Python Academy incluye 4 lecciones en total.
El protocolo de gestor de contexto
Cualquier objeto que defina __enter__ y __exit__ es un gestor de contexto y puede utilizarse con 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")Valor devuelto por __enter__
__enter__ se llama al comienzo del bloque with. Su valor de retorno se asigna a la variable que aparece después de 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) # 42Argumentos de __exit__
__exit__(exc_type, exc_val, exc_tb) recibe información sobre la excepción si se produjo un error. Si no hay ninguna excepción, los tres valores son 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") # suppressedSuprimir excepciones
Devuelva True desde __exit__ para suprimir la excepción. Devuelva False (o no devuelva nada) para permitir que se propague.
class Ignore:
def __enter__(self): return self
def __exit__(self, *args): return True # swallow all exceptions
with Ignore():
1 / 0
print("continues here")Ejemplo de una conexión a una base de datos
Un caso de uso clásico: adquirir una conexión al entrar, confirmar o revertir la transacción y cerrarla al salir.
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 gestor de contexto para medir el tiempo
Mida el tiempo transcurrido registrando el inicio en __enter__ y calculando la diferencia en __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))Anidar gestores de contexto
Se pueden combinar varios gestores de contexto en una sola línea de with.
with open("in.txt") as src, open("out.txt", "w") as dst:
dst.write(src.read())Gestores reutilizables frente a gestores de un solo uso
Los gestores de contexto cuyo __enter__ asigna un recurso nuevo cada vez son reutilizables. Los que agotan un estado interno (como un bloqueo que solo se mantiene una vez) podrían no serlo.
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__ y __aexit__ (asíncronos)
Para los gestores de contexto asíncronos, defina las corrutinas __aenter__ y __aexit__ y utilice 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:
# ...Envolver objetos de archivo
Los objetos de archivo de Python ya implementan el protocolo de gestor de contexto; nunca llame manualmente a f.close().
with open("data.txt", "r") as f:
data = f.read()
# file is closed here automatically
print(f.closed) # TrueImplementar un Lock
Los bloqueos de hilos son gestores de contexto: __enter__ adquiere el bloqueo y __exit__ lo libera.
import threading
lock = threading.Lock()
def update_shared():
with lock:
# critical section
passComprobación rápida
¿Qué debe devolver __exit__ para suprimir una excepción?
Resumen
Implemente __enter__ y __exit__ para crear gestores de contexto. Devuelva el recurso desde __enter__ y gestione la limpieza y la supresión de excepciones en __exit__.
Preguntas frecuentes
¿La lección «Protocolo __enter__ y __exit__» es gratis?
Sí — el texto completo de «Protocolo __enter__ y __exit__» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Python Academy, actualiza a CoddyKit PRO. El curso de Python Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Protocolo __enter__ y __exit__»?
Cree gestores de contexto mediante el protocolo dunder. Practicas Python Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Python Academy?
No se requiere experiencia previa. Python Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Protocolo __enter__ y __exit__»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Python Academy?
Sí. Cada lección de Python Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- La sentencia with en profundidad
- Protocolo __enter__ y __exit__
- contextlib: @contextmanager
- Patrones prácticos de gestores de contexto