Manejo de Archivos en Python: Guía Completa
Aprende el manejo de archivos en Python: abre archivos en cada modo, lee y escribe datos, usa pathlib, gestiona errores y posiciones de forma segura.
El manejo de archivos permite que tus programas almacenen datos de forma permanente y los recuperen más tarde. Este capítulo explica cada operación común con archivos en Python — abrir archivos en distintos modos, leer y escribir datos, navegar dentro de un archivo, especificar la codificación de caracteres y gestionar los errores que surgen en el código real.
La Función open()
Toda operación con archivos en Python comienza con open(). Devuelve un objeto de archivo que expone métodos para leer, escribir y posicionarse dentro del archivo.
file_object = open(file, mode="r", encoding=None)file— la ruta al archivo (un string o un objetopathlib.Path).mode— cómo abrir el archivo (consulta la tabla a continuación).encoding— la codificación de texto, por ejemplo"utf-8". Especifícala siempre para archivos de texto para que tu código funcione igual en todos los sistemas operativos.
Modos de Apertura de Archivos
| Modo | Significado | ¿Crea el archivo? | ¿Trunca el archivo existente? |
|---|---|---|---|
"r" | Lectura (predeterminado) | No | No |
"w" | Escritura | Sí | Sí |
"a" | Añadir | Sí | No |
"x" | Creación exclusiva | Falla si el archivo existe | — |
"r+" | Lectura y escritura | No | No |
"b" | Binario (combinar con los anteriores, p. ej. "rb") | — | — |
"t" | Texto (predeterminado, combinar con los anteriores, p. ej. "rt") | — | — |
Usa Siempre with para Abrir Archivos
La sentencia with (un gestor de contexto) garantiza que el archivo se cierre cuando el bloque finaliza — incluso si se lanza una excepción. Esto previene fugas de recursos y asegura que las escrituras en búfer se vuelquen al disco.
Abre un archivo de forma segura con with
with open("notes.txt", "r", encoding="utf-8") as f:
contents = f.read()
# File is automatically closed hereLlamar a open() sin with y olvidar file.close() es una fuente común de corrupción de datos y errores de "demasiados archivos abiertos" en programas de larga ejecución.
Lectura de Archivos
Python ofrece varias formas de leer el contenido de un archivo.
Leer el Archivo Completo con read()
read() devuelve el contenido completo del archivo como un único string.
Leer un archivo completo
with open("notes.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)Para archivos grandes, esto carga todo en memoria de una vez, lo cual está bien para archivos pequeños pero es ineficiente para logs de varios gigabytes.
Leer un Número Fijo de Caracteres
Pasa un entero a read(n) para leer como máximo n caracteres.
Leer los primeros 20 caracteres
with open("notes.txt", "r", encoding="utf-8") as f:
chunk = f.read(20)
print(repr(chunk))Leer una Línea a la Vez con readline()
readline() devuelve la siguiente línea incluyendo su \n final, o un string vacío al llegar al fin del archivo.
Leer un archivo línea por línea con readline()
with open("notes.txt", "r", encoding="utf-8") as f:
line = f.readline()
while line:
print(line, end="") # line already contains '\n'
line = f.readline()Iterar sobre las Líneas (Más Pythónico)
Iterar directamente sobre un objeto de archivo es el enfoque más eficiente en memoria para leer línea por línea.
Iterar sobre las líneas
with open("notes.txt", "r", encoding="utf-8") as f:
for line in f:
print(line, end="")Leer Todas las Líneas en una Lista con readlines()
readlines() devuelve una lista donde cada elemento es una línea (incluyendo el carácter de nueva línea).
Leer todas las líneas en una lista
with open("notes.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(lines[0]) # first line
print(len(lines)) # total number of linesUsa readlines() cuando necesites acceso aleatorio a líneas específicas por índice. Para el procesamiento secuencial, prefiere el patrón for line in f.
Escritura de Archivos
Modo Escritura ("w")
El modo escritura crea el archivo si no existe y lo trunca (vacía) si ya existe.
Escribir texto en un archivo
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Line one\n")
f.write("Line two\n")Escribir Varias Líneas con writelines()
writelines() acepta un iterable de strings. No añade caracteres de nueva línea automáticamente.
Escribir una lista de líneas
lines = ["apple\n", "banana\n", "cherry\n"]
with open("fruits.txt", "w", encoding="utf-8") as f:
f.writelines(lines)Modo Añadir ("a")
El modo añadir mueve la posición de escritura al final del archivo antes de cada escritura, por lo que el contenido existente nunca se sobrescribe.
Añadir una entrada de log
import datetime
entry = f"{datetime.date.today()} — task complete\n"
with open("log.txt", "a", encoding="utf-8") as f:
f.write(entry)Cada vez que este script se ejecuta, añade una nueva línea a log.txt sin tocar las entradas anteriores.
Modo de Creación Exclusiva ("x")
Usa "x" cuando quieras crear un archivo nuevo y garantizar que no estás sobreescribiendo uno existente. Python lanza FileExistsError si el archivo ya existe.
Crear un archivo solo si no existe
try:
with open("config.txt", "x", encoding="utf-8") as f:
f.write("[settings]\n")
except FileExistsError:
print("config.txt already exists — not overwriting.")Posiciones en Archivos: seek() y tell()
Los objetos de archivo mantienen un puntero de posición interno que avanza a medida que lees o escribes. Puedes inspeccionar y cambiar este puntero.
tell()— devuelve la posición actual en bytes.seek(offset, whence=0)— mueve el puntero.whence=0(predeterminado) es desde el inicio,1es desde la posición actual,2es desde el final.
Volver al inicio con seek(0)
with open("notes.txt", "r", encoding="utf-8") as f:
first_pass = f.read()
f.seek(0) # go back to the start
second_pass = f.read()
print(first_pass == second_pass) # Trueseek() es especialmente útil en el modo "r+" (lectura y escritura) donde puedes leer una sección y luego sobreescribirla en la misma llamada de apertura.
Trabajo con Archivos Binarios
Abre un archivo en modo binario añadiendo "b" al string de modo ("rb", "wb", "ab"). El modo binario te da bytes sin procesar en lugar de strings, lo cual es esencial para imágenes, audio, archivos comprimidos y otros datos no textuales.
Copiar un archivo en modo binario
with open("photo.jpg", "rb") as src:
data = src.read()
with open("photo_backup.jpg", "wb") as dst:
dst.write(data)No especifiques encoding al usar el modo binario — Python lanzará un ValueError si lo intentas.
Manejo de Errores
Las operaciones con archivos pueden fallar de formas predecibles. Envolverlas en bloques try/except hace que tus scripts sean robustos.
Gestionar errores comunes de archivos
try:
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()
except FileNotFoundError:
print("Error: the file does not exist.")
except PermissionError:
print("Error: you do not have permission to read this file.")
except OSError as e:
print(f"OS error: {e}")Excepciones comunes que encontrarás:
| Excepción | Cuándo ocurre |
|---|---|
FileNotFoundError | Al leer un archivo que no existe |
FileExistsError | Al crear un archivo con el modo "x" cuando ya existe |
PermissionError | Al carecer de permiso de lectura/escritura |
IsADirectoryError | Al intentar abrir un directorio como si fuera un archivo |
UnicodeDecodeError | Los bytes del archivo no coinciden con la codificación especificada |
La Alternativa Moderna: pathlib
Python 3.4 introdujo pathlib.Path, un enfoque orientado a objetos para las rutas del sistema de archivos. Los objetos Path funcionan perfectamente con open() y también exponen sus propios métodos de conveniencia read_text() / write_text().
Leer un archivo con pathlib
from pathlib import Path
content = Path("notes.txt").read_text(encoding="utf-8")
print(content)Escribir un archivo con pathlib
from pathlib import Path
Path("output.txt").write_text("Hello, world!\n", encoding="utf-8")read_text() y write_text() abren y cierran el archivo por ti, lo que hace que las lecturas y escrituras únicas sean muy concisas. Usa open() con un bloque with cuando necesites mayor control — por ejemplo, leer un archivo en fragmentos o usar seek().
Renombrar y Mover Archivos
Para renombrar o mover un archivo, usa os.rename() para un renombrado en el mismo sistema de archivos, o shutil.move() cuando necesites mover entre sistemas de archivos distintos.
Renombrar un archivo con os.rename()
import os
os.rename("old_name.txt", "new_name.txt")Mover un archivo con shutil.move()
import shutil
shutil.move("report.txt", "archive/report.txt")shutil.move() funciona incluso cuando el origen y el destino están en unidades distintas; os.rename() lanza OSError en ese caso.
Comprobar si un Archivo Existe
Antes de abrir un archivo para leerlo, puede que quieras confirmar que existe. Usa os.path.exists() o el equivalente de pathlib.
Comprobar la existencia con os.path
import os
if os.path.exists("data.txt"):
print("File found.")
else:
print("File not found.")Comprobar la existencia con pathlib
from pathlib import Path
p = Path("data.txt")
if p.exists():
print("File found.")Ten en cuenta que os.path.exists() y Path.exists() pueden devolver resultados desactualizados en programas con múltiples hilos o procesos. En esos casos, es preferible simplemente intentar abrir el archivo con open() y capturar FileNotFoundError.
Resumen de Funciones Clave
| Operación | Enfoque con os / shutil | Enfoque con pathlib |
|---|---|---|
| Abrir y leer | open(path, "r") | Path(path).read_text() |
| Abrir y escribir | open(path, "w") | Path(path).write_text() |
| Comprobar existencia | os.path.exists(path) | Path(path).exists() |
| Renombrar | os.rename(src, dst) | Path(src).rename(dst) |
| Mover | shutil.move(src, dst) | Path(src).rename(dst) (mismo FS) |
| Eliminar | os.remove(path) | Path(path).unlink() |
Capítulos Relacionados
- Leer Archivos en Python — análisis detallado de cada técnica de lectura
- Escribir / Crear Archivos en Python — escritura, creación y buenas prácticas
- Eliminar Archivos en Python — eliminar archivos y directorios de forma segura
- Try Except en Python — gestión de excepciones en Python
- Sentencia With en Python — cómo funcionan los gestores de contexto