Trabajar con archivos es una de las tareas más frecuentes en programación. Guardar resultados, leer configuraciones, procesar datos en CSV, importar y exportar JSON: todo esto implica abrir archivos, leerlos o escribirlos, y cerrarlos correctamente. Python hace este proceso sencillo y seguro con herramientas integradas que no requieren instalar nada adicional.
En esta guía aprenderás a manejar archivos de texto, CSV y JSON en Python, con ejemplos reales que puedes usar directamente en tus proyectos.
La función open() y los modos de apertura
Todo comienza con la función open(). Recibe la ruta del archivo y un modo de apertura que indica qué quieres hacer con él.
Los modos más importantes son:
"r"— lectura (read). Es el modo por defecto. Falla si el archivo no existe."w"— escritura (write). Crea el archivo si no existe. Si existe, borra su contenido antes de escribir."a"— añadir (append). Crea el archivo si no existe. Si existe, escribe al final sin borrar nada."x"— creación exclusiva. Falla si el archivo ya existe."r+"— lectura y escritura. El archivo debe existir.
A cualquiera de estos modos puedes añadir "b" para trabajar en modo binario ("rb", "wb"), necesario para imágenes, PDFs u otros archivos que no son texto.
La forma correcta de abrir archivos en Python moderno es con el gestor de contexto with. Este se encarga de cerrar el archivo automáticamente al salir del bloque, aunque ocurra un error:
with open("archivo.txt", "r") as f:
contenido = f.read()
# El archivo ya está cerrado aquí, sin necesidad de llamar a f.close()
Evita abrir archivos sin with. Si olvidas llamar a f.close() o si ocurre una excepción antes, el archivo queda abierto y puedes perder datos o tener problemas de rendimiento.
Leer archivos de texto
Tienes tres formas principales de leer el contenido de un archivo de texto, cada una útil en situaciones distintas.
Leer todo el contenido de una vez con read()
read() carga el archivo completo en una sola cadena de texto. Es la forma más simple, pero úsala solo si el archivo es pequeño: si tiene varios gigabytes, consumirá toda esa memoria de golpe.
with open("notas.txt", "r", encoding="utf-8") as f:
contenido = f.read()
print(contenido)
Pasa siempre el argumento encoding="utf-8" cuando trabajas con archivos de texto. Sin él, Python usa la codificación por defecto del sistema operativo, lo que puede causar errores con tildes, eñes u otros caracteres especiales en Windows.
Leer línea a línea con readline()
readline() lee una línea cada vez. Útil cuando necesitas procesar el archivo de forma manual o cuando quieres saltar a una línea específica sin cargar todo.
with open("notas.txt", "r", encoding="utf-8") as f:
primera_linea = f.readline()
segunda_linea = f.readline()
print(primera_linea.strip())
print(segunda_linea.strip())
El método strip() elimina el salto de línea \n al final de cada línea leída, que de otro modo aparecería en la salida.
Leer todas las líneas con readlines() o iterando
readlines() devuelve una lista donde cada elemento es una línea del archivo. La forma más eficiente, sin embargo, es iterar directamente sobre el objeto de archivo, que lee una línea a la vez sin cargar todo en memoria:
# Con readlines(): carga todas las líneas en una lista
with open("notas.txt", "r", encoding="utf-8") as f:
lineas = f.readlines()
for linea in lineas:
print(linea.strip())
# Iterando directamente: más eficiente para archivos grandes
with open("notas.txt", "r", encoding="utf-8") as f:
for linea in f:
print(linea.strip())
Para archivos grandes, siempre prefiere la iteración directa. Lee una línea a la vez y la descarta antes de leer la siguiente, por lo que el uso de memoria es mínimo sin importar el tamaño del archivo.
Escribir archivos de texto
Crear o sobreescribir un archivo con "w"
lineas = [
"Primera línea del archivo\n",
"Segunda línea\n",
"Tercera línea\n"
]
with open("resultado.txt", "w", encoding="utf-8") as f:
f.write("Título del documento\n")
f.write("=" * 20 + "\n")
f.writelines(lineas) # escribe una lista de cadenas de una vez
write() recibe una cadena y la escribe tal cual, sin añadir saltos de línea automáticamente. Tienes que incluir \n cuando quieras una nueva línea. writelines() recibe un iterable de cadenas y las escribe en secuencia, también sin añadir saltos de línea entre ellas.
Añadir contenido sin borrar lo existente con "a"
El modo "a" es ideal para registros de actividad (logs) o para acumular datos con el tiempo:
from datetime import datetime
def registrar_evento(mensaje):
momento = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open("log.txt", "a", encoding="utf-8") as f:
f.write(f"[{momento}] {mensaje}\n")
registrar_evento("Usuario iniciado")
registrar_evento("Archivo procesado: datos.csv")
registrar_evento("Proceso finalizado")
Cada llamada a registrar_evento() abre el archivo, añade una línea al final y lo cierra. El contenido anterior nunca se pierde.
Verificar si un archivo o carpeta existe
Antes de intentar leer un archivo, es buena práctica verificar si existe para evitar errores. El módulo pathlib (recomendado desde Python 3.6) hace esto de forma elegante:
from pathlib import Path
ruta = Path("datos.txt")
if ruta.exists():
print("El archivo existe")
print(f"Tamaño: {ruta.stat().st_size} bytes")
else:
print("El archivo no existe")
# También puedes usarlo directamente al abrir
try:
with open(ruta, "r", encoding="utf-8") as f:
print(f.read())
except FileNotFoundError:
print("No se encontró el archivo.")
pathlib.Path es más moderno y cómodo que el módulo os.path. Permite construir rutas de forma segura en cualquier sistema operativo usando el operador /:
from pathlib import Path
# Construir rutas de forma segura (funciona en Windows, Mac y Linux)
carpeta = Path("documentos") / "proyectos" / "python"
archivo = carpeta / "notas.txt"
# Crear la carpeta si no existe
carpeta.mkdir(parents=True, exist_ok=True)
print(archivo) # documentos/proyectos/python/notas.txt
print(archivo.suffix) # .txt
print(archivo.stem) # notas
print(archivo.parent) # documentos/proyectos/python
Trabajar con archivos CSV
El formato CSV (Comma-Separated Values) es uno de los más usados para intercambiar datos entre aplicaciones. Python incluye el módulo csv en su biblioteca estándar.
Leer un archivo CSV
import csv
# Supongamos que empleados.csv tiene este contenido:
# nombre,departamento,salario
# Ana García,Desarrollo,4500
# Carlos López,Diseño,3800
# María Torres,Marketing,4100
with open("empleados.csv", "r", encoding="utf-8", newline="") as f:
lector = csv.DictReader(f) # cada fila es un diccionario
for fila in lector:
print(f"{fila['nombre']} trabaja en {fila['departamento']}")
print(f" Salario: ${fila['salario']}")
Usa siempre newline="" al abrir archivos CSV: así evitas que Python inserte saltos de línea extra en algunos sistemas operativos. DictReader usa la primera fila como claves del diccionario, lo que hace el código más legible que acceder por índice numérico.
Escribir un archivo CSV
import csv
empleados = [
{"nombre": "Ana García", "departamento": "Desarrollo", "salario": 4500},
{"nombre": "Carlos López", "departamento": "Diseño", "salario": 3800},
{"nombre": "María Torres", "departamento": "Marketing", "salario": 4100},
]
with open("empleados_nuevo.csv", "w", encoding="utf-8", newline="") as f:
campos = ["nombre", "departamento", "salario"]
escritor = csv.DictWriter(f, fieldnames=campos)
escritor.writeheader() # escribe la fila de encabezados
escritor.writerows(empleados)
print("Archivo CSV creado correctamente.")
Filtrar y transformar datos de un CSV
Un caso de uso real: leer un CSV, filtrar las filas que cumplen una condición y guardar el resultado en un nuevo archivo.
import csv
with open("empleados.csv", "r", encoding="utf-8", newline="") as entrada, \
open("desarrollo.csv", "w", encoding="utf-8", newline="") as salida:
lector = csv.DictReader(entrada)
campos = lector.fieldnames
escritor = csv.DictWriter(salida, fieldnames=campos)
escritor.writeheader()
for fila in lector:
if fila["departamento"] == "Desarrollo":
escritor.writerow(fila)
print("Filtrado completado.")
Trabajar con archivos JSON
JSON es el formato estándar para APIs y configuraciones. El módulo json de Python convierte entre estructuras de Python (diccionarios, listas) y texto JSON de forma directa.
Leer un archivo JSON
import json
# config.json contiene:
# {
# "host": "localhost",
# "puerto": 5432,
# "base_de_datos": "mi_app",
# "debug": true
# }
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f) # convierte JSON a diccionario de Python
print(config["host"]) # localhost
print(config["puerto"]) # 5432
print(type(config["puerto"])) # <class 'int'> (los tipos se preservan)
json.load() lee desde un archivo. json.loads() (con s de string) convierte una cadena JSON en lugar de un archivo.
Escribir un archivo JSON
import json
usuarios = [
{"id": 1, "nombre": "Ana", "activo": True, "puntos": 1500},
{"id": 2, "nombre": "Carlos", "activo": False, "puntos": 800},
{"id": 3, "nombre": "María", "activo": True, "puntos": 2200},
]
with open("usuarios.json", "w", encoding="utf-8") as f:
json.dump(usuarios, f, ensure_ascii=False, indent=2)
print("JSON guardado.")
Los argumentos más útiles de json.dump() son indent para formatear el JSON de forma legible (sin él queda todo en una línea) y ensure_ascii=False para que los caracteres como tildes y eñes se guarden tal cual en lugar de convertirse a secuencias de escape como \u00e9.
Actualizar datos en un archivo JSON
Un patrón muy común: leer el JSON, modificar los datos y volver a guardarlo.
import json
from pathlib import Path
ruta = Path("usuarios.json")
# Leer
with open(ruta, "r", encoding="utf-8") as f:
usuarios = json.load(f)
# Modificar: desactivar al usuario con id 2
for usuario in usuarios:
if usuario["id"] == 2:
usuario["activo"] = True
usuario["puntos"] += 100
break
# Guardar
with open(ruta, "w", encoding="utf-8") as f:
json.dump(usuarios, f, ensure_ascii=False, indent=2)
print("Usuario actualizado.")
Leer y escribir archivos binarios
Para archivos que no son texto (imágenes, PDFs, archivos comprimidos) debes usar el modo binario "rb" / "wb". En este modo lees y escribes bytes en lugar de cadenas de texto.
# Copiar una imagen
with open("foto_original.jpg", "rb") as origen:
datos = origen.read()
with open("foto_copia.jpg", "wb") as destino:
destino.write(datos)
print(f"Archivo copiado: {len(datos)} bytes")
Para copiar archivos, en la práctica es mejor usar shutil.copy() que hace lo mismo en una sola línea y maneja casos especiales correctamente:
import shutil
shutil.copy("foto_original.jpg", "foto_copia.jpg")
shutil.copy2("foto_original.jpg", "carpeta_destino/") # copy2 preserva los metadatos
Listar y gestionar archivos con pathlib
Además de leer y escribir, frecuentemente necesitas listar archivos en una carpeta, renombrarlos o eliminarlos.
from pathlib import Path
carpeta = Path("documentos")
# Listar todos los archivos (no subcarpetas)
for archivo in carpeta.iterdir():
if archivo.is_file():
print(archivo.name)
# Listar solo archivos .txt
for archivo in carpeta.glob("*.txt"):
print(archivo.name)
# Búsqueda recursiva en subcarpetas
for archivo in carpeta.rglob("*.csv"):
print(archivo)
# Renombrar
archivo = Path("notas_viejas.txt")
archivo.rename("notas_2026.txt")
# Eliminar un archivo
Path("temporal.txt").unlink(missing_ok=True) # missing_ok evita error si no existe
# Eliminar una carpeta vacía
Path("carpeta_vacia").rmdir()
Ejemplo completo: procesar un log y generar un reporte
Para cerrar, un ejemplo que integra lectura de texto, procesamiento de datos y escritura de JSON y CSV.
Supongamos que tenemos un archivo accesos.log con entradas como:
2026-05-01 08:23:11 INFO Usuario ana@mail.com inició sesión
2026-05-01 08:45:30 ERROR Usuario pedro@mail.com contraseña incorrecta
2026-05-01 09:10:05 INFO Usuario ana@mail.com cerró sesión
2026-05-01 09:30:22 ERROR Usuario luis@mail.com cuenta bloqueada
2026-05-01 10:00:00 INFO Usuario maria@mail.com inició sesión
import csv
import json
from pathlib import Path
from collections import Counter
errores = []
conteo = Counter()
with open("accesos.log", "r", encoding="utf-8") as f:
for linea in f:
partes = linea.strip().split(" ", 3)
if len(partes) < 4:
continue
fecha, hora, nivel, mensaje = partes
conteo[nivel] += 1
if nivel == "ERROR":
errores.append({
"fecha": fecha,
"hora": hora,
"mensaje": mensaje
})
# Guardar errores en CSV
with open("errores.csv", "w", encoding="utf-8", newline="") as f:
escritor = csv.DictWriter(f, fieldnames=["fecha", "hora", "mensaje"])
escritor.writeheader()
escritor.writerows(errores)
# Guardar resumen en JSON
resumen = {
"total_entradas": sum(conteo.values()),
"por_nivel": dict(conteo),
"total_errores": len(errores)
}
with open("resumen.json", "w", encoding="utf-8") as f:
json.dump(resumen, f, ensure_ascii=False, indent=2)
print(f"Procesadas {resumen['total_entradas']} entradas.")
print(f"Errores encontrados: {resumen['total_errores']}")
print("Archivos generados: errores.csv, resumen.json")
Resumen
Estos son los puntos clave para trabajar con archivos en Python:
- Usa siempre
with open(...) as fpara garantizar que el archivo se cierre correctamente. - Especifica siempre
encoding="utf-8"al abrir archivos de texto para evitar problemas con caracteres especiales. - Elige el modo de apertura según lo que necesites:
"r"para leer,"w"para crear o sobreescribir,"a"para añadir. - Para archivos grandes, itera directamente sobre el archivo en lugar de cargar todo con
read()oreadlines(). - Usa el módulo
csvconDictReaderyDictWriterpara leer y escribir CSVs de forma robusta. - Usa el módulo
jsonconjson.load()yjson.dump()para archivos JSON; no olvidesensure_ascii=Falseeindent=2. - Usa
pathlib.Pathpara construir rutas, verificar existencia, listar carpetas y gestionar archivos de forma portable entre sistemas operativos.
No hay comentarios todavía. Sé el primero en compartir tu opinión.