In Python, the process of converting an object to JSON format is called serialization (or encoding), and the reverse process is called deserialization (or decoding). Python provides the json.dumps() method for encoding and the json.loads() method for decoding.
These methods can handle basic data types (like strings, integers, and lists) but when working with custom Python objects, special handling is required.
json.dumps() - Encoding Python Objects into JSON
json.dumps() function is used to convert a Python object into a JSON-formatted string, let's look at some of the examples:
import json
# Basic Python dictionary
d = {"a": 0, "b": 0, "c": 0}
# Encoding: Converting the dictionary to JSON string
j = json.dumps(d)
print(j)
print(type(j))
Output
{"a": 0, "b": 0, "c": 0}
<class 'str'>
Encoding Custom Python Object
import json
class Student:
def __init__(self, name, roll_no, address):
self.name = name
self.roll_no = roll_no
self.address = address
def to_json(self):
'''Converts the instance of this class to a JSON string'''
return json.dumps(self, default=lambda o: o.__dict__, indent=4)
class Address:
def __init__(self, city, street, pin):
self.city = city
self.street = street
self.pin = pin
# Creating instances
address = Address("Bulandshahr", "Adarsh Nagar", "203001")
student = Student("Raju", 53, address)
# Encoding custom object
student_json = student.to_json()
print(student_json)
print(type(student_json))
Output
{
"name": "Raju",
"roll_no": 53,
"address": {
"city": "Bulandshahr",
"street": "Adarsh Nagar",
"pin": "203001"
}
}
<class 'str'>
Customizing JSON Serialization with JSONEncoder
You can also customize the serialization process by subclassing JSONEncoder and overriding the default() method. This approach allows more control over how the object is serialized.
Using JSONEncoder for Custom Serialization
import json
from json import JSONEncoder
class Student:
def __init__(self, name, roll_no, address):
self.name = name
self.roll_no = roll_no
self.address = address
class Address:
def __init__(self, city, street, pin):
self.city = city
self.street = street
self.pin = pin
# Custom encoder class
class EncodeStudent(JSONEncoder):
def default(self, o):
return o.__dict__
# Creating instances
address = Address("Bulandshahr", "Adarsh Nagar", "203001")
student = Student("Raju", 53, address)
# Encoding custom object using EncodeStudent class
s_json = json.dumps(student, indent=4, cls=EncodeStudent)
print(s_json)
print(type(s_json))
Output
{
"name": "Raju",
"roll_no": 53,
"address": {
"city": "Bulandshahr",
"street": "Adarsh Nagar",
"pin": "203001"
}
}
<class 'str'>
Custom Decoding with object_hook
The object_hook parameter in json.loads() allows you to define how the JSON data is converted back into a Python object. By providing a custom object_hook function, you can control the deserialization process.
Custom Decoding
import json
# Custom decoder function
def as_complex(dct):
if '__complex__' in dct:
return complex(dct['real'], dct['imag'])
return dct
# JSON string representing a complex number
json_data = '{"__complex__": true, "real": 1, "imag": 2}'
# Decoding using custom function
com_num = json.loads(json_data, object_hook=as_complex)
print(com_num)
print(type(com_num))
Output
(1+2j) <class 'complex'>