24 · Leer y escribir archivos
open(), modos, el with statement, lectura línea a línea y por qué especificar siempre encoding='utf-8' te salva de sorpresas en Windows.
`open(path, mode)` devuelve un **objeto de archivo** — un handle a través del cual lees o escribes bytes. El `with` statement es un **gestor de contexto** que garantiza que el archivo se cierra en el momento en que el bloque indentado termina, incluso si se lanza una excepción dentro.
Sin esto:
Sin handles de archivo explícitos, no hay forma de leer datos de entrenamiento del disco, escribir registros de métricas ni guardar y cargar modelos serializados. Todo pipeline de ML empieza y termina con I/O.
Para leer o escribir un archivo primero necesitas un handle — un objeto que representa la conexión abierta al archivo en disco. open(path, mode) crea ese handle. El string mode controla si estás leyendo ("r"), escribiendo ("w", trunca primero), añadiendo ("a") o usando una variante binaria ("rb", "wb"). El modo por defecto es "r". Dejar un archivo abierto más tiempo del necesario desperdicia recursos del SO y puede corromper datos si el programa falla antes de vaciar el búfer. El with statement lo resuelve automáticamente: sin importar cómo termine el bloque — retorno normal, excepción, break — Python llama f.close() por ti.
Python (in browser)
`f.writelines(iterable)` escribe cada elemento sin añadir separadores — debes incluir `\n` tú mismo. `f.read()` devuelve todo el archivo como un único string; `f.readlines()` devuelve una lista de líneas, cada una aún con su salto de línea al final.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Iterar `for line in f:` lee una línea a la vez — Python nunca carga todo el archivo en memoria. Siempre llama `.rstrip()` (o `.rstrip("\n")`) para eliminar el salto de línea final que `readline` preserva; olvidarlo provoca salida con doble espacio al hacer `print`.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
El `with` statement llama a `f.__exit__()` al final del bloque, lo que vacía cualquier byte en búfer y cierra el descriptor de archivo del SO. Sin él, un crash entre `open()` y `close()` filtra el descriptor — en procesos de larga duración esto agota el límite del SO y lanza `OSError: Too many open files`.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
¿Qué hace abrir un archivo con el modo `"a"`?
- `open(path, mode, encoding="utf-8")` devuelve un handle de archivo. Modos: `"r"` lectura, `"w"` escritura (trunca), `"a"` append, `"rb"`/`"wb"` binario. Especifica siempre `encoding` para archivos de texto.
- Usa `with open(...) as f:` — el gestor de contexto garantiza que `f.close()` se llama incluso si se lanza una excepción dentro del bloque.
- Itera `for line in f:` para leer línea a línea de forma eficiente en memoria. Llama `.rstrip()` para eliminar el salto de línea final.
Los datos de entrenamiento viven en archivos CSV, JSONL o texto plano en disco — `open()` es la puerta de entrada. El registro de métricas escribe pérdida y exactitud después de cada época en un archivo `.log` abierto en modo `"a"`. Los checkpoints de modelos usan modo binario internamente: `torch.save(state_dict, "checkpoint.pt")` y `np.save("weights.npy", arr)` de numpy escriben bytes crudos. `encoding="utf-8"` es obligatorio al leer corpus de texto multilingüe para tareas de NLP.
Si lo quitas: Sin I/O de archivos, cada dataset tendría que estar codificado directamente en el script y todo modelo entrenado se perdería al salir del proceso. Los archivos son la capa de persistencia de todo pipeline de ML.