Manejo de archivos .json con Python



@eduardo_gpg

Número de visitas 15046

Tiempo de lectura 5 min

26 Junio 2021

Sin temor a equivocarme puedo decirte que, tarde o temprano, en algún momento de nuestra vida como desarrollador, tendremos que trabajar con objetos JSON. Ya sea para poder enviar o recibir información o inclusive para poder almacenar y/o procesarla. 😦

No me mal interprete, el trabajar con objetos JSON no es algo que no me guste, al contrario, creo que los objetos de tipo JSON sin duda llegaron a revolucionar la forma en la cuan manejamos la información. Y es justo por ello que en esta ocasión me gustaría compartir un pequeño post sobre cómo podemos trabajar con este tipo de estructura en Python. Que te adelanto, es algo mucho más sencillo de lo que parece.

Bien, entonces sin más dilación, comencemos con la lectura. 🍻

Módulo JSON

Comencemos con la pregunta obligada ¿Qué es un objeto JSON? Bueno, la respuesta más sencilla es que JSON, por sus siglas al ingles JavaScript Object Notation, es un formato ligero para el intercambio de datos. Utilizando este formato seremos capaces de, tanto enviar como recibir información. Esto, principalmente, a través de internet.

Aquí un ejemplo:

{
    "nombre": "Eduardo",
    "edad": 27,
    "correo": "eduardo78d@gmail.com",
    "cursos": ["Python", "MongoDB", "Flask"]
}

Como podemos observar, la estructura se conforma mediante pares de llaves-valores. Cada llaves tiene la posibilidad de almacenar deferentes tipos de datos: ya sean strings, enteros, flotantes, booleanos, listas, etc... 😃 Y en caso la estructura posea 2 o más pares clave-valor estos deberán encontrarse separados mediante una coma (,).

Esto sin duda te debe resultar familiar, ya que cada una de estas características también describen a los diccionarios en Python. Quizás la diferencia más notable entre un objeto JSON y un diccionario es que, las llaves para un objeto JSON deberán ser (de forma obligatoria) strings, y por su parte un diccionario puede poseer cualquier objeto inmutable como llave. Por todo lo demás, prácticamente son lo mismo. 😲

Con todo esto en mente podemos concluir que, para trabajar con Objetos JSON en Python lo haremos utilizando diccionarios.

Afortunadamente para nosotros, en Python existe el módulo json que nos permite convertir objetos JSON a diccionarios de una forma muy sencilla. Veamos un par de ejemplos.

Comencemos con algo sencillo. Por ejemplo, generemos un diccionario utilizando un string con formato JSON. Para esto haremos uso de la función loads.

import json

json_object =  '''{
    "nombre": "Eduardo",
    "edad": 27,
    "correo": "eduardo78d@gmail.com",
    "cursos": ["Python", "MongoDB", "Flask"]
}'''

user = json.loads(json_object)
print(user)

Obtendríamos el siguiente resultado en consola:

{'nombre': 'Eduardo', 'edad': 27, 'correo': 'eduardo78d@gmail.com', 'cursos': ['Python', 'MongoDB', 'Flask']}

Cool, 🥳 una vez con el diccionario ya seremos capaces de obtener los valores con respecto a cada una de sus llaves.

>>> user['nombre']
Eduardo

>>> user['edad']
27

>>> user['cursos']
["Python", "MongoDB", "Flask"]

Ahora, si quisiéramos hacer lo inverso, usaremos la función dumps. La función dumps nos permite serializar un objeto Python a un objeto JSON.

import json

user = {
    "nombre": "Eduardo",
    "edad": 27,
    "correo": "eduardo78d@gmail.com",
    "cursos": ["Python", "MongoDB", "Flask"]
}

json_object = json.dumps(user)

print(json_object)
print(type(json_object))

Obteniendo como resultado la siguiente salida.

{"nombre": "Eduardo", "edad": 27, "correo": "eduardo78d@gmail.com", "cursos": ["Python", "MongoDB", "Flask"]}
<class 'str'>

Visualizamos que el nuevo objeto es tipo es string; con lo cual confirmamos que hemos generado un objeto JSON utilizando un diccionario. 🥳

Y ¿Qué pasa si queremos serializar un objeto propio? Bueno, lo intentemos. 🤐

import json

class Usuario:
    def __init__(self, username, email):
        self.username = username
        self.email = email


usuario = Usuario('eduardo_gpg', 'eduardo78d@gmail.com')
data = json.dumps(usuario)

print(data)

Si ejecutamos obtendremos un error. Indicándonos que no es posible serializar nuestro objeto. 😰

TypeError: Object of type Usuario is not JSON serializable

En estos casos, cuando deseemos serializar objetos propios, lo que podemos hacer es simplemente generar un diccionario a partir de cada uno de los atributos del objeto que deseamos serializar. Una vez con el diccionario, seremos capaces de utilizar la función dumps sin ningún problema.

Si recordamos, los atributos de nuestro objeto se encuentran en el atributo dict. Así que podemos utilizar dicho atributo. Claro, siempre y cuando queremos serializar todos los atributos del objeto. 🤓

usuario = Usuario('eduardo_gpg', 'eduardo78d@gmail.com')
data = json.dumps(usuario.__dict__)

print(data)

Obteniendo el siguiente resultado.

{"username": "eduardo_gpg", "email": "eduardo78d@gmail.com"}

Archivos .json

Perfecto, ya sabemos tanto crear diccionarios a partir de objetos JSON y viceversa, crear objetos JSON a partir de diccionarios. Ahora aprenderemos tanto leer como crear archivos .json.

Que te parece si comenzamos con la lectura. Y para este nuevo ejemplo hare uso del archivo users.json Un archivo que posee un listado de usuarios en formato JSON.

Para la lectura de este archivo el código pudiera quedar de la siguiente manera:

import json

with open('users.json') as f:
    payload = json.load(f)

    for user in payload['users']:
        print(user)

Danto como resultado.

{'nombre': 'Eduardo', 'edad': 27}
{'nombre': 'Raquel', 'edad': 29}
{'nombre': 'Fernando', 'edad': 25}
{'nombre': 'Guadalupe', 'edad': 30} 

Para este ejemplo imprimimos en consola todos los usuarios de la lista. 🐍

Ahora, quizás hayas notado que para este ejemplo no estamos haciendo uso de la función loads, si no de la función load (en singular). Bueno, esto se debe a que la función load la usaremos únicamente cuando queramos leer el contenido de un archivo .json en forma binario, por su parte, la función loads la usaremos para generar un diccionario utilizando un string con formato JSON.

Perfecto, ahora hagamos lo inverso, creemos un archivo .json a partir de un objeto Python. Para ello me apoyaré del siguiente listado de usuarios.

users = [
      {
        "nombre": "Eduardo",
        "edad": 27
      },
      {
        "nombre": "Raquel",
        "edad": 29
      },
      {
        "nombre": "Fernando",
        "edad": 25
      },
      {
        "nombre": "Guadalupe",
        "edad": 30
      }
]

Nuestro código pudiera quedar de la siguiente forma:

import json

with open('users.json', 'w') as f:
  json.dump(users, f, indent=4)

Utilizando la función dump (En singular) podremos serializar un objeto Python a un objeto json. Lo interesante de esta función es que, además de ello, nos permite escribir sobre un archivo, e inclusive, definir la indentación que usaremos.

Para este ejemplo indico que el listado será serializado para ser escrito en el archivo users.json con una indentación de 4 espacios. 🤯

Lo interesante de la función dumps es que, en caso deseemos serializar el objeto utilizando un orden en las llaves, podemos hacer uso del parámetro sort_keys.

Aquí un ejemplo.

import json

usuario = {
    'username': 'eduardo_gpg',
    'nombre': 'Eduardo Ismael',
    'age': 27,
    'correo': 'eduardo78d@gmail.com'
}

data = json.dumps(usuario, indent=4, sort_keys=True)
print(data)

Danto como resultado:

{
    "age": 27,
    "correo": "eduardo78d@gmail.com",
    "nombre": "Eduardo Ismael",
    "username": "eduardo_gpg"
}

Las llaves, como podemos observar, ahora se encuentran en orden alfabético, de forma ascendente.

Conclusión

JSON es definitivamente uno de los estándares más importantes en nuestra actualidad. Es por ello que es necesario sepamos trabajar con él en los diferentes lenguajes de programación que utilicemos en nuestro día a día.

Para Python, como pudimos observar, es relativamente sencillo. Basta con importar el módulo json y utilizar alguna de las 4 funciones que vimos en este post.

  • load
  • loads
  • dump
  • dumps

Pudiendo así crear objetos JSONs utilizando objetos Python o directamente con archivos. 🍹

Si quieres conocer más acerca de este módulo de invito a que le eches un vistazo al link de la documentación oficial.


¿El contenido te resulto de ayuda?

Para poder dejar tu opinión es necesario ser un usuario autenticado. Login

Más Tips y Ejercicios 🐍

Adquiere una subscripción PyWombat por tan solo $3 USD. al mes.

Conoce los beneficios de ser usuario premium:
Niveles desbloqueados: Ten accesos a todos los niveles de ejercicios. 🔓
Nuevo límite: Incrementa tu límite de ejercicios por semana. 🚀
Contenido único: Recibe semanalmente recursos exclusivos de Python (Videos, Artículos y Capitulos del libro PyWombat, comienza como desarrollador Python. 🐍