Skip to content

Python de Cero a Pro - Cap. 15 - Persistencia con JSON

Este capítulo es el paso 1 de nuestra práctica secuencial para construir un sistema de gestión profesional.

  1. Módulo de Persistencia JSON (Estás aquí) 📍
  2. Módulo de Procesamiento de Fechas 🗓️
  3. Módulo de Seguridad y Ofuscación 🛡️
  4. Arquitectura de Modelos de Datos 🧩
  5. Interfaz de Usuario TUI Profesional 🎮

Módulo de Persistencia JSON (save_json.py) 🗄️

Section titled “Módulo de Persistencia JSON (save_json.py) 🗄️”

En este capítulo aprenderemos a darle “memoria” a nuestros programas. Sin persistencia, todos los datos que un usuario escriba se perderán al cerrar la terminal. Usaremos el formato JSON (JavaScript Object Notation), que es el estándar mundial para intercambiar datos.

modules/save_json.py
import json
import os
def save_json(data, filename, path=""):
"""Guarda datos en JSON asegurando soporte para acentos (UTF-8)"""
# Construimos la ruta completa (Funciona en Windows y Linux)
fullpath = os.path.join(path, filename)
content = []
# Si el archivo ya existe, leemos lo que tiene primero
if os.path.exists(fullpath):
try:
with open(fullpath, 'r', encoding='utf-8') as f:
content = json.load(f)
# Nos aseguramos de que siempre sea una lista
if not isinstance(content, list): content = [content]
except (json.JSONDecodeError, UnicodeDecodeError):
content = []
try:
# Añadimos el nuevo dato a la lista
content.append(data)
# Creamos la carpeta si no existe
os.makedirs(path, exist_ok=True)
# Escribimos todo de vuelta al archivo
with open(fullpath, 'w', encoding='utf-8') as f:
json.dump(content, f, indent=4, ensure_ascii=False)
return True
except Exception as e:
print(f"=== Error al guardar: {e} ===")
return False
def load_json(filename, path=""):
"""Carga datos desde JSON con codificación UTF-8"""
fullpath = os.path.join(path, filename)
if not os.path.exists(fullpath): return []
try:
with open(fullpath, 'r', encoding='utf-8') as f:
return json.load(f)
except (json.JSONDecodeError, UnicodeDecodeError):
return []
def find_in_json(query_key, query_value, filename, path=""):
"""Busca elementos específicos dentro del archivo."""
data = load_json(filename, path)
return [item for item in data if item.get(query_key) == query_value]
# --- Ejemplo de Ejecución Directa (Para Pruebas) ---
if __name__ == "__main__":
try:
test_data = {"id": 1, "nombre": "Prueba UTF-8", "mensaje": "¡Hola Qué Pasa Linux! ✨"}
print("--- Intentando guardar datos ---")
if save_json(test_data, "test.json", "data/test/"):
print("✅ Datos guardados correctamente en data/test/test.json")
print("--- Intentando cargar datos ---")
cargado = load_json("test.json", "data/test/")
print(f"📖 Datos recuperados: {cargado}")
except Exception as e:
print(f"❌ Error fatal en la prueba: {e}")

🧠 Conceptos Detallados para Principiantes 🔍

Section titled “🧠 Conceptos Detallados para Principiantes 🔍”

Imagina que es una libreta donde escribes datos en forma de lista o etiquetas. Python puede leer esta libreta y convertirla en diccionarios y listas instantáneamente. Es mucho mejor que un archivo .txt común porque mantiene la estructura de los datos (números son números, booleanos son booleanos).

Por defecto, muchas computadoras viejas no entienden la “ñ” o los acentos. Al usar encoding='utf-8' le decimos a Python: “Usa el traductor universal de caracteres”. Esto garantiza que los nombres de tus usuarios se vean bien en cualquier país.

En Windows, las carpetas se separan con \ y en Linux con /. Si escribes la ruta a mano, tu programa fallará en algún sistema. os.path.join detecta en qué computadora estás y pone la barra correcta automáticamente. ¡Esto es programación profesional!

Es el proceso de “aplanar” tus objetos de Python para que quepan en un archivo de texto.

  • indent=4: Hace que el archivo se vea bonito y ordenado (legible para humanos).
  • ensure_ascii=False: Evita que Python convierta las tildes en códigos raros como \u00e1.

¿Por qué esto hace tu sistema Escalable? 🚀

Section titled “¿Por qué esto hace tu sistema Escalable? 🚀”

Al separar el guardado de datos en un módulo aparte (save_json.py), no tienes que escribir código de archivos cada vez que quieras guardar un Usuario, un Producto o una Venta. Simplemente “llamas” al módulo. Esto permite que tu sistema crezca sin que tu código se vuelva un desorden.


  1. Crea un archivo: Usa la función save_json para guardar un diccionario con tu nombre y color favorito.
  2. Verificación: Abre el archivo generado con un editor de texto y observa cómo indent=4 creó una estructura limpia.
  3. Manejo de Errores: Intenta guardar datos en una ruta protegida (como el disco C directamente) y observa cómo el bloque try/except captura el error sin que el programa “explote”.

Siguiente: Módulo de Procesamiento de Fechas