2.27. Leer y escribir

Los archivos viven en el disco; Python los alcanza a través de open(), que devuelve un objeto de archivo cuyos métodos leen y escriben los bytes subyacentes.

2.27.1. open y modos

El primer argumento es la ruta; el segundo es el modo – una cadena corta que le indica a Python cómo se usará el archivo:

  • "r" – lectura (por defecto). Abre un archivo existente para leer.

  • "w" – escritura. Crea un archivo nuevo o trunca uno existente dejándolo vacío.

  • "a" – anexar. Abre un archivo para escribir al final sin truncarlo.

  • "b" añadido a cualquiera de los anteriores ("rb", "wb", "ab") – modo binario. El contenido del archivo es bytes en lugar de str.

f = open("notes.txt", "r")
text = f.read()
f.close()

2.27.2. Usa un gestor de contexto

El patrón anterior filtra el descriptor del archivo si algo entre open() y close lanza. La solución es la sentencia with (consulta gestores de contexto):

with open("notes.txt") as f:
    text = f.read()

# f is closed here, even if read() failed

Esta es la forma estándar – escríbelo así siempre.

2.27.3. Lectura

Los objetos de archivo admiten varios estilos de lectura:

  • io.IOBase.read() – lee el archivo completo (o N bytes) y lo devuelve como una sola cadena (u objeto bytes).

  • io.IOBase.readline() – lee una línea, incluyendo el "\n" final.

  • Iterar el archivo directamente produce las líneas de una en una, con un uso de memoria mucho menor que leer el archivo completo de una vez.

with open("log.txt") as f:
    for line in f:
        print(line.rstrip())

str.rstrip() elimina el salto de línea final antes de imprimir para que la salida no quede con doble espaciado.

2.27.4. Escritura

Abre el archivo en modo "w" y usa io.IOBase.write():

with open("out.txt", "w") as f:
    f.write("hello\n")
    f.write("world\n")

io.IOBase.write() no añade un salto de línea – escribe exactamente los bytes (o caracteres, en modo texto) que le das.

2.27.5. Texto frente a binario

El modo texto (por defecto, "r" / "w" sin "b") decodifica los bytes entrantes en str usando una codificación por defecto, y codifica los str salientes de vuelta a bytes. Úsalo para configuración, registros, JSON – cualquier cosa que sea texto.

El modo binario ("rb" / "wb") omite el paso de decodificación y devuelve bytes. Úsalo para imágenes, registros empaquetados con struct, capturas de red – cualquier cosa donde cada byte importe y el archivo no sea legible por humanos.

2.27.6. Listar y eliminar archivos

El módulo os expone las operaciones de sistema de archivos que no están en el propio objeto de archivo:

import os

for name in os.listdir("/"):
    print(name)

Captura OSError alrededor de estas cuando el archivo o directorio pueda no estar presente – la operación es uno de los lugares habituales donde aparecen excepciones en scripts reales.