3. Serialización en la web

La serialización es un proceso mediante el cual podemos convertir objetos de un programa en ejecución en flujos de bytes capaces de ser almacenados en dispositivos, bases de datos o de ser enviados a través de la red y, posteriormente, ser capaces de reconstruirlos en los equipos donde sea necesario.

Hoy en día, los desarrolladores de aplicaciones web enfrentan el reto de incluir en sus programas algoritmos de serialización/deserialización y transmisión de datos que permitan convertir objetos de diferentes tipos a texto, transportarlos y finalmente volver a ser el objeto que eran antes.

La serialización es un proceso para convertir datos en grandes cantidades de bits llamados en inglés Stream, que luego pueden ser enviados por la red o almacenados en bases de datos. Lo opuesto a esto se conoce como deserialización, que sería volver un objeto a su estado natural. Este proceso lo utilizan la mayoría de aplicaciones en internet.

Existen dos tipos de serialización/deserialización:

  1. El que tiene formato de texto para poder ser interpretado por el ser humado y las computadoras.

    Nota

    El presente artículo se enfoca en el formato de texto que puede ser interpretado por el ser humano, por medio de formato JSON.

  2. La binaria, que solo es interpretada por las computadoras.

    Nota

    En el artículo referente al módulo pickle se enfoca en la serialización/deserialización binaria.

3.1. JavaScript Object Notation - JSON

El JavaScript Object Notation - JSON (o en español Notación de Objetos de JavaScript) es un formato ligero de intercambio de datos. Leerlo y escribirlo es simple para humanos, mientras que para las máquinas es simple interpretarlo y generarlo. Está basado en un subconjunto del Lenguaje de Programación JavaScript, Standard ECMA-262 3rd Edition - Diciembre 1999.

JSON es un formato de texto que es completamente independiente del lenguaje pero utiliza convenciones que son ampliamente conocidos por los programadores de la familia de lenguajes C, incluyendo C, C++, C#, Java, JavaScript, Perl, Python, y muchos otros. Estas propiedades hacen que JSON sea un lenguaje ideal para el intercambio de datos.

JSON ha trascendido sus orígenes para convertirse en un lenguaje agnóstico y ahora es reconocido como el estándar para el intercambio de datos.

../_images/json_logo.png

Figura 3.1, Logotipo de JavaScript Object Notation (JSON)

La popularidad de JSON puede atribuirse al soporte nativo por parte del lenguaje JavaScript, lo que se traduce en un excelente rendimiento de análisis sintáctico en los navegadores web. Además, la sencilla sintaxis de JSON permite tanto a humanos como a ordenadores leer y escribir datos JSON sin esfuerzo.

A diferencia del módulo pickle, el formato JSON tiene la ventaja de tener implementaciones en muchos lenguajes (especialmente JavaScript). Se usa más ampliamente para la comunicación entre el servidor web y el cliente en una API REST, pero también es útil para otras necesidades de comunicación entre aplicaciones.

3.1.1. Estructura y formato JSON

JSON está constituído por dos estructuras:

  • Una colección de pares de nombre/valor. En varios lenguajes esto es conocido como un objeto, registro, estructura, diccionario, tabla hash, lista de claves o un arreglo asociativo.

  • Una lista ordenada de valores. En la mayoría de los lenguajes, esto se implementa como arreglos, vectores, listas o sequencias.

Estas son estructuras universales; virtualmente todos los lenguajes de programación las soportan de una forma u otra. Es razonable que un formato de intercambio de datos que es independiente del lenguaje de programación se base en estas estructuras.

En JSON, se presentan de estas formas:

  1. Un objeto es un conjunto desordenado de pares nombre/valor. Un objeto comienza con { llave de apertura y termine con llave de cierre }. Cada nombre es seguido por : dos puntos y los pares nombre/valor están separados por , coma.

  2. Un arreglo es una colección de valores. Un arreglo comienza con [ corchete izquierdo y termina con corchete derecho ]. Los valores se separan por , coma.

  3. Un valor puede ser una cadena de caracteres con comillas dobles, o un número, o true o false o null, o un objeto o un arreglo. Estas estructuras pueden anidarse.

  4. Una cadena de caracteres es una colección de cero o más caracteres Unicode, encerrados entre comillas dobles, usando barras divisorias invertidas como escape. Un carácter está representado por una cadena de caracteres de un único carácter. Una cadena de carateres es parecida a una cadena de caracteres C o Java.

  5. Un número es similar a un número C o Java, excepto que no se usan los formatos octales y hexadecimales.

  6. Los espacios en blanco pueden insertarse entre cualquier par de símbolos. Exceptuando pequeños detalles de encoding, esto describe completamente el lenguaje.

Veamos su estructura básica con un ejemplo que representa un ficha basica de un cliente. A continuación se muestra un ejemplo de un archivo JSON:

Listado de código de bloque 3.1, Ejemplo de archivo JSON
1
2
3
4
5
6
{
    "nombre": "Leonardo",
    "apellido": "Caballero",
    "codigo_postal": "5001",
    "telefono": "+58-412-4734567"
}

Estas son las características principales del formato JSON:

  • Posee una secuencia de pares clave-valor rodeados por un par de llaves {}.

  • Cada clave se asocia a un valor con este formato:

    "clave": <valor>
    

    Truco

    Los valores que incluyen comillas simples deben estar rodeados por comillas dobles.

    Los pares clave-valor deben estar separados por una coma. Solo el último par no debe estar seguido de una coma.

    {
        "nombre": "Manuel",
        "apellido": "Matos",
        "codigo_postal": "4001", # ¡Coma!
        "telefono": "+58-414-2360943"
    }
    

    Advertencia

    Los comentarios no están permitidos en JSON.

    Truco

    Generalmente estructuramos los archivos JSON con distintos niveles de indentación para que la información sea más fácil de leer. De forma automática con Python puedes controlar la indentación a usar.


3.2. Módulo json

Nota

Propósito: usar el módulo que incorpora Python para codificar y decodificar JavaScript Object Notation (JSON).

El módulo json expone una API familiar a los usuarios de los módulos de la biblioteca estándar marshal y pickle. Este le permite codificar objetos de Python como cadenas en formato JSON y decodifiquelas en objetos de Python.

Además proporciona una API similar al módulo pickle para convertir objetos de Python en memoria a una representación serializada conocida como JavaScript Object Notation (JSON).

Por hacer

TODO terminar de escribir esta sección.

3.2.1. Codificación

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import json

# Data a escribir
clientes_data = {
    "clientes": [
        {
            "nombre": "Leonardo",
            "apellido": "Caballero",
            "codigo_postal": "5001",
            "telefono": "+58-412-4734567",
        }
    ]
}
# Abriendo archivo para escribir un tipo diccionario 'clientes_data'
with open("clientes.json", mode="w", encoding="utf-8") as json_nuevo:
    json.dump(clientes_data, json_nuevo)
    # Cerrar el archivo después de escribirlo
    json_nuevo.close()
    print("✅ Se escribió el archivo JSON 'clientes.json'.")

Por hacer

TODO terminar de escribir esta sección.

3.2.2. Decodificación

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import json

# Abrir el archivo en modo lectura
with open("clientes.json", encoding="utf-8") as json_leido:
    # Leyendo desde archivo JSON
    data = json.load(json_leido)
    for cliente in data["clientes"]:
        print(f"📜 Nombre:", cliente["nombre"])
        print(f"📜 Apellido:", cliente["apellido"])
        print(f"📜 Código postal:", cliente["codigo_postal"])
        print(f"📜 Teléfono:", cliente["telefono"])
        print(f"📜 Datos detallados: {cliente}\n")
    # Cerrar el archivo después de leerlo
    json_leido.close()
    print("✅ Se leyó el archivo JSON 'clientes.json'.")

Por hacer

TODO terminar de escribir esta sección.

3.2.3. Práctica - Caso real

A continuación se presenta una práctica más real de implementar el uso de proyectos con el módulo json para leer y escribir un archivo JSON basado en un tipo diccionario:

3.2.4. Estructura de archivos

Para crear la estructura de archivos del proyecto JSON debe ejecutar los siguientes comandos:

Crear y acceder al directorio json en un solo comando, ejecutando el siguiente comando:

mkdir -p ~/proyectos/json && cd $_

El comando anterior crea la siguiente estructura de directorios:

proyectos/
└── json/

Si tiene la estructura de archivo previa, entonces puede continuar con la siguiente sección.

A continuación se presenta y explica el uso de cada archivo para este proyecto:

Archivo json_reading_writing.py

Módulo de principal del programa.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""Programa para escribir y leer un archivo JSON"""

import json
import logging
import os

logging.basicConfig(level=logging.INFO)

# Ruta del archivo
RUTA = os.path.join(os.path.dirname(os.path.abspath(__file__)))
# Nombre de archivo JSON
ARCHIVO_JSON = "clientes.json"
# Data a escribir
clientes_data = {
    "clientes": [
        {
            "nombre": "Leonardo",
            "apellido": "Caballero",
            "codigo_postal": "5001",
            "telefono": "+58-412-4734567",
        },
        {
            "nombre": "Ana",
            "apellido": "Poleo",
            "codigo_postal": "6302",
            "telefono": "+58-426-5831297",
        },
        {
            "nombre": "Manuel",
            "apellido": "Matos",
            "codigo_postal": "4001",
            "telefono": "+58-414-2360943",
        },
    ]
}


try:
    # Abriendo archivo para escribir un tipo diccionario 'clientes_data'
    with open(
        os.path.join(RUTA, ARCHIVO_JSON), mode="w", encoding="utf-8"
    ) as json_nuevo:
        json.dump(clientes_data, json_nuevo)
        # Cerrar el archivo después de escribirlo
        json_nuevo.close()
        logging.info(f"✅ Se escribió el archivo JSON '{ARCHIVO_JSON}'.\n")
    # Abrir el archivo en modo lectura
    with open(os.path.join(RUTA, ARCHIVO_JSON), encoding="utf-8") as json_leido:
        # Leyendo desde archivo JSON
        data = json.load(json_leido)
        for cliente in data["clientes"]:
            print(f"📜 Nombre:", cliente["nombre"])
            print(f"📜 Apellido:", cliente["apellido"])
            print(f"📜 Código postal:", cliente["codigo_postal"])
            print(f"📜 Teléfono:", cliente["telefono"])
            print(f"📜 Datos detallados: {cliente}\n")
        # Cerrar el archivo después de leerlo
        json_leido.close()
        logging.info(f"✅ Se leyó el archivo JSON '{ARCHIVO_JSON}'.")
except FileNotFoundError as e:
    print(f"❌ Error: No se encontró el archivo: {e}")
except Exception as e:
    print(f"❌ Error inesperado: {e}")

Importante

Usted puede descargar el código usado en esta sección haciendo clic en el siguiente enlace:

Truco

Para ejecutar el código json_reading_writing.py, abra una consola de comando, acceda al directorio donde se encuentra el programa:

proyectos/
└── json/
    └── json_reading_writing.py

Si tiene la estructura de archivo previa, entonces ejecute el siguiente comando:

python3 json_reading_writing.py

El anterior código al ejecutar debe mostrar el siguiente mensaje:

INFO:root:✅ Se escribió el archivo JSON 'clientes.json'.

📜 Nombre: Leonardo
📜 Apellido: Caballero
📜 Código postal: 5001
📜 Teléfono: +58-412-4734567
📜 Datos detallados: {'nombre': 'Leonardo', 'apellido': 'Caballero', 'codigo_postal': '5001', 'telefono': '+58-412-4734567'}

📜 Nombre: Ana
📜 Apellido: Poleo
📜 Código postal: 6302
📜 Teléfono: +58-426-5831297
📜 Datos detallados: {'nombre': 'Ana', 'apellido': 'Poleo', 'codigo_postal': '6302', 'telefono': '+58-426-5831297'}

📜 Nombre: Manuel
📜 Apellido: Matos
📜 Código postal: 4001
📜 Teléfono: +58-414-2360943
📜 Datos detallados: {'nombre': 'Manuel', 'apellido': 'Matos', 'codigo_postal': '4001', 'telefono': '+58-414-2360943'}

INFO:root:✅ Se leyó el archivo JSON 'clientes.json'.

La ejecución anterior generar la siguiente estructura:

proyectos/
└── json/
    ├── clientes.json
    └── json_reading_writing.py

Archivo clientes.json

Archivo en formato JSON llamado clientes.json la cual no se incluye ya que cada vez que se inicia el programa json_reading_writing.py se sustituye y crea nuevamente, para cuidar la creación de los datos iniciales.

Así de esta forma puede leer y escribir registros en un archivo JSON usando el módulo json.


Ver también

Consulte la sección de lecturas suplementarias del entrenamiento para ampliar su conocimiento en esta temática.



¿Cómo puedo ayudar?

¡Mi soporte está aquí para ayudar!

Mi horario de oficina es de lunes a sábado, de 9 AM a 5 PM. UTM - Madrid, España.

La hora aquí es actualmente 7:35 PM UTM.

Mi objetivo es responder a todos los mensajes dentro de un día hábil.

Contrata mi increíble soporte profesional