0Pricing
Python Academy · Lección

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)  # 42

Argumentos 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")  # suppressed

Suprimir 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 False

Un 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)  # True

Implementar 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
        pass

Comprobació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

  1. La sentencia with en profundidad
  2. Protocolo __enter__ y __exit__
  3. contextlib: @contextmanager
  4. Patrones prácticos de gestores de contexto
← Volver a Python Academy