with open(...) as f: es la forma estándar de trabajar con archivos a través de un administrador de contexto. Con este enfoque, Python garantiza el cierre automático del archivo al salir del bloque with, incluso si se produce una excepción. Esto evita fugas de descriptores de archivos y bloqueos de archivos.
Dentro del bloque, se puede trabajar con el archivo utilizando los métodos del objeto (f.read(), f.write(), etc.). Después de salir del bloque (incluso si hay un error), se llama al método f.close().
Ejemplo:
with open('data.txt', 'w') as f: f.write('¡Hola!') # Aquí el archivo ya está cerrado
Pregunta frecuente:
¿Se puede estar seguro de que el archivo abierto a través de
opense cerrará inmediatamente después de salir del bloquewith, incluso si se produce una excepción en medio del bloque?
Respuesta: Sí, eso es precisamente lo que garantiza el contrato del administrador de contexto: independientemente de las excepciones, se llama al método __exit__ al salir del bloque, lo que lleva al cierre del archivo. Esta es la principal ventaja en comparación con la llamada explícita a f.close().
Historia
En un gran proyecto, las entradas de registro se realizaban a través de open('log.txt', 'a') y la llamada explícita a f.write(), pero se olvidaron de f.close(). Después de un tiempo prolongado, el proceso agotó todos los descriptores de archivos del SO, y el servicio dejó de funcionar.
Historia
En el sistema de monitoreo se utilizaba la apertura continua de archivos a través de open, sin manejar excepciones. Cuando ocurría un error, el archivo seguía abierto, lo que provocaba bloqueos al intentar abrirlo nuevamente desde otro proceso.
Historia
Un desarrollador implementó la lectura de un archivo grande a través de open y realizó un return en medio de la función, sin cerrar el archivo. Como resultado, varias de esas operaciones llevaron al desbordamiento de los recursos de archivos, y el SO comenzó a bloquear nuevas aperturas.