JSON (JavaScript Object Notation) is a standard text-based data exchange format that represents structured data in key-value pairs and arrays. If you’ve ever worked on a web or mobile application project, you’ve likely encountered JSON or had to work with it in some way. It is a commonly used data format that allows you to transfer large amounts of text-based data through APIs, with or without encoding. In this article, we will explore Python's json module and learn how to encode and decode JSON data.

Serialization

Serialization is the process of converting Python objects into JSON format, making them suitable for storage or transmission. We can convert a Python object into a JSON string using the dumps function.

import json

data = {
    "name": "John Doe",
    "email": "john.doe@gmail.com",
    "languages": ["English", "French"],
    "address": {
        "city": "New York, NY",
        "country": "USA"
    },
    "birthYear": 1989,
}

json_string = json.dumps(data)

print(json_string)

When you run the code above, the output will look like this:

{
  "name": "John Doe",
  "email": "john.doe@gmail.com",
  "languages": [
    "English",
    "French"
  ],
  "address": {
    "city": "New York, NY",
    "country": "USA"
  },
  "birthYear": 1989
}

We can also convert an instance of a class into JSON string. To do this, we should use the internal __dict__ attribute of the object.

import json

class Employee:
    def __init__(self, name, age, languages):
        self.name = name
        self.age = age
        self.languages = languages
    

employee1 = Employee("John", 30, ["English", "Spanish"])

json_string = json.dumps(employee1.__dict__)

print(json_string)

When you run the code above, the instance of Employee class will be converted into the JSON below:

{
  "name": "John",
  "age": 30,
  "languages": [
    "English",
    "Spanish"
  ]
}

Deserialization

As you might expect, deserialization is the process of converting a JSON string into a Python object. The loads function allows us to perform this conversion.

import json

json_string = '''
{
  "name": "John Doe",
  "languages": ["English", "French"],
  "address": {
    "city": "San Francisco",
    "state": "California",
    "country": "United States of America"
  }
}
'''

json_object = json.loads(json_string)

name = json_object['name']
languages = json_object['languages']
address = json_object['address']

print(f'Name: {name}')
print("Languages:")

for lang in languages:
    print(f'  - {lang}')

print('Address:')
print(f'  City: {address["city"]}')
print(f'  State: {address["state"]}')
print(f'  Country: {address["country"]}')

When you run the code above, the output will look like this:

Name: John Doe
Languages:
  - English
  - French
Address:
  City: San Francisco
  State: California
  Country: United States of America

The loads function parses the given JSON and creates a Python object that holds the data, allowing you to work with it.

It is also possible to convert a JSON string into an instance of a custom Python class by adding an extra step to the parsing process.

Let’s return to the previous example with the Employee class.

import json
from typing import Type, TypeVar, Dict

T = TypeVar('T', bound='Employee')

class Employee:
    def __init__(self, name, age, languages):
        self.name = name
        self.age = age
        self.languages = languages
    
    @classmethod
    def from_dict(cls: Type[T], data: Dict) -> T:
        return cls(**data)
    

json_string = '''
{
  "name": "John",
  "age": 30,
  "languages": [
    "English",
    "Spanish"
  ]
}
'''

data = json.loads(json_string)
custom_instance = Employee.from_dict(data)

name = custom_instance.name
age = custom_instance.age
languages = custom_instance.languages

print(f"Name: {name}")
print(f"Age: {age}")

print("Languages:")
for language in languages:
    print(f" - {language}")

T is a type variable constrained to the Employee class (or subclasses of Employee). It ensures that methods like from_dict can return the correct type of instance.

@classmethod makes the from_dict method callable on the class itself. The from_dict method dynamically creates an instance of cls (Employee) using the dictionary keys as arguments to the constructor.

When you run the code above, the output will look like this:

Name: John
Age: 30
Languages:
 - English
 - Spanish

Conclusion

Working with JSON in Python is a fundamental skill for developers, especially in today’s world of APIs and data-driven applications. Python’s built-in json module makes it easy to parse, manipulate, and serialize JSON data, whether you’re dealing with simple dictionaries or complex nested structures. By combining JSON with custom classes, as we explored, you can easily map structured data into Python objects.

AUTHOR
PUBLISHED 16 March 2025
TOPICS