Curso de Python / Convertir y guardar datos JSON

JSON, abreviatura de JavaScript Object Notation, es un formato de texto para datos estructurados. json.load() y dump() trabajan con archivos, mientras que loads() y dumps() trabajan con cadenas; el formato no conserva cualquier objeto o tipo posible de Python.

Relacionar los valores JSON con Python

JSON Python
object dict
array list
string str
true / false / null True / False / None

Las claves y cadenas JSON utilizan comillas dobles. Las comillas simples propias de algunos literales Python y los comentarios no son extensiones que puedas añadir libremente a JSON. Una tupla puede convertirse en una lista después de guardar y cargar; las fechas y los objetos Decimal necesitan una política de conversión explícita.

La referencia oficial del módulo json describe qué valores admite y cómo se configuran la codificación y la decodificación.

Guardar un registro Unicode y leerlo de nuevo

El ejemplo utiliza café para mostrar un nombre con un carácter no ASCII. Reemplaza expenses-demo.json, por lo que debes trabajar en una carpeta desechable. Guarda el script como json_demo.py en UTF-8 y ejecuta python json_demo.py con el entorno del proyecto seleccionado. En macOS o Ubuntu, utiliza python3 fuera del entorno si corresponde.

import json
from pathlib import Path

data = {"currency": "KRW", "expenses": [{"name": "café", "amount": 8000}]}
path = Path("expenses-demo.json")
path.write_text(json.dumps(data, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8")
loaded = json.loads(path.read_text(encoding="utf-8"))
amount = loaded["expenses"][0]["amount"]
if type(amount) is not int or amount < 0:
    raise ValueError("invalid amount")
print(loaded["expenses"][0]["name"])
print(amount)

La salida esperada es:

café
8000

Abre el archivo generado para comprobar que contiene un objeto con una lista de gastos. El programa vuelve a leerlo, consulta el importe y valida su tipo y su rango antes de mostrar el resultado.

Distinguir análisis del formato y validación

Que un JSON se interprete correctamente no demuestra que contenga las claves obligatorias, las colecciones, los tipos y los rangos que exige la aplicación. El ejemplo utiliza type(amount) is int para excluir booleanos, porque bool es una subclase de int. isinstance() puede ser apropiado si deseas admitir subclases; el contrato determina la comprobación.

Función Operación
load(archivo) Archivo → objeto Python
loads(texto) Cadena → objeto Python
dump(objeto, archivo) Objeto Python → archivo
dumps(objeto) Objeto Python → cadena JSON

dumps() devuelve texto: no crea un archivo por sí misma. Además, allow_nan=False rechaza constantes numéricas no estándar al serializar. No convierte automáticamente toda lectura posterior en una validación estricta de entradas externas; también necesitas reglas para constantes no estándar y claves repetidas.

Separar representación de caracteres y codificación

ensure_ascii=False conserva caracteres no ASCII legibles en el texto en lugar de sustituirlos por secuencias de escape. No elige la codificación del archivo: UTF-8 se configura por separado. La opción indent cambia la presentación sin cambiar el significado de los datos.

Un JSON mal formado produce JSONDecodeError. Corrige las comillas o la coma final incorrecta en lugar de utilizar eval(). En el objeto Python de origen, prueba los importes -1 y True, comprueba que la validación los rechaza y después restaura 8000.

Esta práctica presupone una estructura concreta. Un importador general también debe comprobar las claves y la forma de la lista que rodea al importe. Las solicitudes HTTP y las respuestas JSON aplican la misma distinción a datos recibidos de un servidor.