Almacenamiento y serialización de datos con la biblioteca estándar de Python: json, pickle, csv
Para guardar datos en archivos o enviarlos por la red, se necesita serialización. Python ofrece tres herramientas estándar, cada una con un enfoque distinto: json, pickle, csv.

json: formato de texto legible por humanos, excelente para intercambio entre lenguajes.pickle: formato binario que guarda objetos de Python tal cual, potente pero con riesgos de seguridad.csv: formato de texto simple para datos tabulares, muy versátil.
En este artículo organizamos la elección de cada módulo según el tipo de datos y el destino.
1. JSON
1.1 Visión general
JSON (JavaScript Object Notation) es basado en texto y independiente de lenguaje. Se usa ampliamente en archivos de configuración, respuestas/solicitudes de API y logs. En Python se maneja con el módulo json.
1.2 API principal (lo más usado)
json.dump(obj, fp, ...)/json.load(fp, ...): guardar/leer desde archivo.json.dumps(obj, ...)/json.loads(s, ...): convertir a/desde cadena.
Opciones útiles:
ensure_ascii=False– guarda caracteres internacionales sin escapar.indent=2– formato legible.default=...– función para convertir tipos desconocidos.
1.3 Ejemplo básico
import json
data = {
"name": "Alice",
"age": 30,
"skills": ["Python", "Data Science"]
}
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open("data.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded)
1.4 Solución sencilla a la limitación de tipos
JSON admite nativamente dict, list, str, int/float, bool, None. Para tipos como datetime, se puede usar default.
import json
from datetime import datetime, timezone
payload = {"created_at": datetime.now(timezone.utc)}
def to_jsonable(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Not JSON serializable: {type(obj)!r}")
s = json.dumps(payload, default=to_jsonable, ensure_ascii=False)
print(s)
1.5 Ventajas y desventajas
Ventajas
- Intercambio entre lenguajes.
- Texto: depuración y control de versiones.
- No ejecuta código al cargar.
Desventajas
- Expresión limitada de tipos (datetime, set, Decimal, binario).
- En datos grandes, puede ser menos eficiente.
2. Pickle
2.1 Visión general
pickle serializa objetos de Python en binario. Al cargar, se recupera un objeto casi idéntico.
Es útil cuando:
- Se desea conservar objetos complejos (clases, estructuras anidadas, modelos entrenados).
- No se necesita interoperabilidad con otros lenguajes.
Evita usarlo cuando:
- La fuente no es confiable (
pickle.load()puede ejecutar código). - Se necesita compartir con sistemas no Python.
2.2 API principal (los 4 más usados)
pickle.dump(obj, file, protocol=...)pickle.load(file)pickle.dumps(obj, protocol=...)pickle.loads(data)
Ejemplo típico de archivo:
import pickle
data = {"a": [1, 2, 3], "b": ("x", "y")}
with open("data.pkl", "wb") as f:
pickle.dump(data, f)
with open("data.pkl", "rb") as f:
loaded = pickle.load(f)
print(loaded)
2.3 ¿Qué es protocol y por qué importarlo?
protocol define la versión del formato de pickle. El valor por defecto es el más adecuado para la versión actual de Python.
- Si se necesita compatibilidad con versiones antiguas, se debe fijar un protocolo bajo.
- Para optimizar tamaño y velocidad, se suele usar
pickle.HIGHEST_PROTOCOL.
import pickle
with open("data.pkl", "wb") as f:
pickle.dump({"x": 1}, f, protocol=pickle.HIGHEST_PROTOCOL)
2.4 Precaución real (importante)
pickle.load() ejecuta el código embebido en el pickle. Por eso, nunca cargues un pickle de origen desconocido.
- Si el objetivo es compartir, opta por
jsonu otro formato de texto.
2.5 Ventajas y desventajas
Ventajas
- Guarda prácticamente cualquier objeto de Python.
- Generalmente más rápido que
jsonpara objetos complejos.
Desventajas
- Riesgo de seguridad.
- No interoperable con otros lenguajes.
- Cambios en la definición de clases pueden romper pickles antiguos.
3. CSV
3.1 Visión general
CSV (Comma-Separated Values) es el formato más sencillo para datos tabulares. Se usa en hojas de cálculo, exportaciones e importaciones de datos y logs simples.
3.2 API principal (lo más usado)
csv.reader,csv.writer– listas.csv.DictReader,csv.DictWriter– diccionarios (más cómodo).
3.3 Ejemplo con DictWriter/DictReader
import csv
data = [
{"name": "Alice", "age": 30, "city": "Seoul"},
{"name": "Bob", "age": 25, "city": "Busan"},
]
with open("people.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
writer.writeheader()
writer.writerows(data)
with open("people.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
loaded = list(reader)
print(loaded)
3.4 Puntos de precaución (3)
- Usar
newline=""– evita saltos de línea dobles en Windows. - Todos los valores son cadenas – conviene convertir tipos manualmente.
- Separadores y comillas dentro de los datos – el módulo
csvmaneja estos casos.
3.5 Ventajas y desventajas
Ventajas
- Muy ligero y ampliamente soportado.
- Ideal para datos tabulares simples.
Desventajas
- No representa estructuras anidadas.
- Falta de información de tipo.
4. Comparación y guía de selección
| Característica | JSON | Pickle | CSV |
|---|---|---|---|
| Compatibilidad | Muy buena | Solo Python | Muy buena |
| Legibilidad | Alta | Baja (binario) | Alta |
| Expresión de tipos | Limitada | Alta | Limitada |
| Seguridad | Relativamente segura | Precaución necesaria | Relativamente segura |
| Estructura | Árbol (anidado) | Objeto completo | Tabla (fila/columna) |
Resumen rápido
- Intercambio entre sistemas →
json. - Guardar objetos de Python íntegros →
pickle(con precaución). - Exportar/leer datos tabulares →
csv.
5. Guardar y cargar los mismos datos con los tres formatos
import json, pickle, csv
data = [
{"id": 1, "name": "Alice", "score": 95.5},
{"id": 2, "name": "Bob", "score": 88.0},
]
# 1) JSON
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open("data.json", "r", encoding="utf-8") as f:
json_loaded = json.load(f)
# 2) Pickle
with open("data.pkl", "wb") as f:
pickle.dump(data, f)
with open("data.pkl", "rb") as f:
pickle_loaded = pickle.load(f)
# 3) CSV
with open("data.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["id", "name", "score"])
writer.writeheader()
writer.writerows(data)
with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
csv_loaded = [
{"id": int(row["id"]), "name": row["name"], "score": float(row["score"])}
for row in reader
]
print(json_loaded)
print(pickle_loaded)
print(csv_loaded)
- CSV requiere conversión de tipos al leer.
- Pickle es cómodo pero exige cuidado con la fuente.
6. Conclusión
Con la biblioteca estándar de Python, la serialización y el almacenamiento de datos cubren una amplia gama de necesidades.
- Si el objetivo es intercambio y legibilidad, elige
json. - Si necesitas conservar objetos de Python tal cual, usa
pickle(con precaución). - Si trabajas con datos tabulares simples,
csves la opción más ligera.
Selecciona el módulo que mejor se adapte a la forma y al propósito de tus datos, y obtendrás una solución rápida y limpia.