3.4 JSON¶
JSON (JavaScript Object Notation) es un formato de texto para guardar e intercambiar datos. Es el formato más usado entre aplicaciones y servidores web, porque es compacto, fácil de leer para una persona y todos los lenguajes saben procesarlo.
{
"usuarios": [
{"id": 1, "nombre": "Juan", "edad": 30},
{"id": 2, "nombre": "Ana", "edad": 25}
]
}
Qué contiene un JSON¶
| En JSON | Ejemplo | En Python es... |
|---|---|---|
Objeto { } |
{"id": 1} |
un mapa (o un objeto de una clase) |
Array [ ] |
[1, 2, 3] |
una lista |
| Texto | "Ana" |
una cadena |
| Número | 25 · 3.5 |
un entero o decimal |
| Booleano | true · false |
un booleano |
| Nulo | null |
el valor nulo |
Las reglas son estrictas: las claves y los textos van siempre entre comillas dobles, no se admite una coma al final de una lista ni de un objeto y no hay comentarios. La mayoría de errores con JSON son una de estas tres cosas.
Python incluye el módulo json: json.loads(texto) convierte un texto en diccionarios y listas, json.load(archivo) lo hace desde un archivo, y json.dumps(datos, indent=2) / json.dump(datos, archivo) hacen lo contrario. Añade ensure_ascii=False para que las tildes se escriban tal cual en lugar de como \u00e9.
Leer, modificar y escribir¶
import json
def mostrar(datos):
for u in datos["usuarios"]:
print(f"ID: {u['id']}, Nombre: {u['nombre']}, Edad: {u['edad']}")
texto = '{"usuarios": [{"id": 1, "nombre": "Juan", "edad": 30}, {"id": 2, "nombre": "Ana", "edad": 25}]}'
datos = json.loads(texto)
mostrar(datos)
datos["usuarios"][1]["edad"] = 26 # actualizar
datos["usuarios"].append({"id": 3, "nombre": "Eva", "edad": 22}) # insertar
datos["usuarios"] = [u for u in datos["usuarios"] if u["id"] != 1] # eliminar
print("--- después de los cambios ---")
mostrar(datos)
print(json.dumps(datos, indent=2, ensure_ascii=False))
Salida:
ID: 1, Nombre: Juan, Edad: 30
ID: 2, Nombre: Ana, Edad: 25
--- después de los cambios ---
ID: 2, Nombre: Ana, Edad: 26
ID: 3, Nombre: Eva, Edad: 22
{
"usuarios": [
{
"id": 2,
"nombre": "Ana",
"edad": 26
},
{
"id": 3,
"nombre": "Eva",
"edad": 22
}
]
}
El proceso siempre es el mismo en tres pasos:
- Convertir el texto en estructuras del lenguaje (mapas, listas u objetos).
- Trabajar con ellas como con cualquier mapa o lista. Se actualiza asignando (
datos["usuarios"][1]["edad"] = 26), se inserta conappendy se elimina reconstruyendo la lista sin ese elemento, como con cualquier lista o diccionario. - Convertirlas de nuevo en texto, con sangría si lo van a leer personas.
Trabajar con archivos y controlar los errores¶
Los datos suelen estar en un archivo. Al leerlo pueden pasar dos cosas que hay que controlar siempre: que el archivo no exista o que su contenido no sea un JSON válido. Un JSON mal formado lanza json.JSONDecodeError.
import json
import os
def cargar(ruta):
if not os.path.exists(ruta):
print(f"No existe el archivo '{ruta}'")
return None
try:
with open(ruta, encoding="utf-8") as f:
return json.load(f)["usuarios"]
except json.JSONDecodeError:
print(f"El archivo '{ruta}' no contiene un JSON válido")
return None
if __name__ == "__main__":
cargar("no_existe.json")
with open("malo.json", "w", encoding="utf-8") as f:
f.write("{ esto no es json")
cargar("malo.json")
datos = {"usuarios": [{"id": 1, "nombre": "Juan", "edad": 30}, {"id": 2, "nombre": "Ana", "edad": 25}]}
with open("bueno.json", "w", encoding="utf-8") as f:
json.dump(datos, f)
usuarios = cargar("bueno.json")
print(f"Cargados {len(usuarios)} usuarios")
os.remove("malo.json")
os.remove("bueno.json")
Salida:
No existe el archivo 'no_existe.json'
El archivo 'malo.json' no contiene un JSON válido
Cargados 2 usuarios
Comprobar la existencia antes de abrir y capturar el error de formato permite dar un mensaje claro en vez de que el programa se detenga. Los archivos de texto se guardan en UTF-8, la codificación habitual del JSON.
Errores frecuentes¶
| Error | Cómo evitarlo |
|---|---|
| Comillas simples en el texto del JSON | En JSON solo valen las dobles |
| Una coma de más al final | Quítala: JSON no la permite |
| Esperar un número y recibir texto (o al revés) | Comprueba el tipo o convierte |
| Pedir una clave que no existe | Comprueba con las consultas seguras del apartado 3.2 |
| Perder las tildes al guardar | Usa UTF-8 en lectura y escritura |
Para practicar¶
Haz el ejercicio 3.4 de JSON, la gestión de usuarios en un archivo.