Lección 36 de 45 · Python intermedio

Context managers

Un context manager organiza una tarea con principio y final: adquiere un recurso, te deja usarlo y garantiza la limpieza al salir.

withCiclo de vidaNúcleo + ampliación
Índice · Lección 36/45
La idea importante no es “with abre archivos”; es “with garantiza una salida ordenada”

Algunos recursos necesitan limpieza: archivos que deben cerrarse, bloqueos que deben liberarse o conexiones que deben terminar. El problema aparece cuando hay varios caminos de salida o una excepción interrumpe el flujo.

Un context manager reúne la preparación y la limpieza en un mismo protocolo.

Evidencia de aprendizaje

Explicar adquisición → uso → liberación y por qué with protege la limpieza incluso si algo falla.

El ejemplo cotidiano ya lo conoces: abrir, usar y cerrar un archivo

El bloque delimita cuánto tiempo necesitas el recurso
from io import StringIO

with StringIO("hola") as archivo:
    contenido = archivo.read()
    print(contenido)

print(archivo.closed)

Dentro del with, el recurso está disponible. Al abandonar el bloque, se ejecuta su cierre aunque no hayas escrito close() manualmente.

La ventaja crece cuando el bloque puede terminar por un return o una excepción.

Ampliación: cómo se construye un context manager

Cuando usar with ya sea natural, puedes mirar debajo de la abstracción: @contextmanager ejecuta código antes de yield, pausa durante el bloque y usa finally para garantizar la limpieza. No necesitas construir uno propio para dominar la habilidad principal de esta lección.

La habilidad esencial es usar bien el ciclo de vida

1. adquirirabrir archivo / conexión / recurso
2. usarhacer el trabajo dentro del bloque
3. liberarcerrar incluso si hubo una excepción

Para un principiante, with es más importante que aprender a construir un context manager propio.

Reescribe la apertura manual usando with. La salida debe ser la misma, pero la limpieza debe quedar garantizada por la estructura del código.

Salida esperada
ok
with.py
La salida aparecerá aquí.

Necesito una pista
  • Usa un with open(...) para escribir y otro para leer.
  • El archivo queda disponible con as archivo solo dentro del bloque.
Ver una solución razonada
with open("mensaje.txt", "w", encoding="utf-8") as archivo:
    archivo.write("ok")

with open("mensaje.txt", "r", encoding="utf-8") as archivo:
    print(archivo.read())
Ampliación: construir tu propio context manager

@contextmanager, yield y finally permiten crear un ciclo de vida propio. Déjalo como ampliación hasta que usar with te resulte natural.

from contextlib import contextmanager

@contextmanager
def recurso():
    print("abrir")
    try:
        yield
    finally:
        print("cerrar")

Lee cualquier with como un pequeño ciclo de vida

  • Entrar: preparar o adquirir el recurso.
  • Usar: ejecutar el bloque con el recurso disponible.
  • Salir: liberar o restaurar lo que corresponda, incluso ante un fallo.
Puedes avanzar cuando...

puedes explicar qué problema evita with sin mencionar archivos: garantizar una limpieza asociada a un bloque de uso.