Explain Codes LogoExplain Codes Logo

Serializing class instance to JSON

python
serialization
json-encoder
custom-serializers
Anton ShumikhinbyAnton Shumikhin·Mar 6, 2025
TLDR

The first step to serialize a class instance to JSON is to implement a to_dict() method in your class that converts instance attributes to a dictionary. Use json.dumps() with a default parameter that refers to the to_dict method. This could be implemented as follow:

import json class MyClass: def __init__(self, attribute): self.attribute = attribute def to_dict(self): return self.__dict__ # Converts the instance attributes to a dictionary json_string = json.dumps(MyClass("value"), default=MyClass.to_dict) print(json_string) # {"attribute": "value"}

This snippet of code allows you to convert class instances into a JSON-formatted string.

Dealing with tricky instances

Sometimes, you may deal with complex objects that require custom serialization solutions. Fret not! Let's handle this situation step by step.

Customizing with JSONEncoder subclass

To gain full control over the serialization process, you can create a custom subclass of JSONEncoder and redefine the .default() method. It enables us to revenge on complex objects:

import json from json import JSONEncoder from datetime import date class CustomEncoder(JSONEncoder): def default(self, obj): if isinstance(obj, date): return obj.isoformat() # No complex date for JSON! return obj.__dict__ # Serialize all other objects as usual class YourClass: def __init__(self, created_at): self.created_at = created_at # Class with datetime attribute encoded_json = json.dumps(YourClass(date.today()), cls=CustomEncoder) # BAM! Custom encoding

Just like that, we have full control over how date.today() is serialized.

Lambda shortcut

If subclassing feels overcomplicated, fearlessly use a lambda function:

encoded_json = json.dumps(your_object, default=lambda obj: obj.__dict__) # Lambda to the rescue

JSONPickle for the rescue

For objects with complicated identities, like custom data types or recursive data structures, opt for JSONPickle. It can get you out of these muds:

import jsonpickle serializable_string = jsonpickle.encode(your_complex_object) # Morphs your object into JSON restored_object = jsonpickle.decode(serializable_string) # And it can change it back!

Making it personal

Add custom serializers for specific types and manage data structures.

def custom_serializer(obj): if isinstance(obj, (date, time)): return obj.isoformat() # No need for complex date/time formats raise TypeError("Type not serializable") json_string = json.dumps(your_object, default=custom_serializer) # Precisely what you need

Trust but verify

A must-do step is validate the output, ensuring only instance variables are included:

json_string = json.dumps(vars(your_object)) # vars() gets your instance attributes

This is a great way to avoid the inclusion of class variables.

Using serialization in real scenarios

Serialization is particularly useful in web applications, specifically in HTTP requests.

HTTP requests chit-chat

With the requests library, serialize your object before sending it away in a POST request:

import requests headers = {'Content-Type': 'application/json'} # Dress it up for the party response = requests.post('https://api.example.com/data', json=json.dumps(your_object.__dict__), headers=headers) # Off you go!

This is how you send your JSON over the Internet.

Advanced serialization with JSONPickle

Consider JSONPickle for scenarios standard JSON serialization doesn't cover:

# Persistent storage example with open('config.json', 'w') as f: f.write(jsonpickle.encode(app_config)) # POOF! your app config is now a JSON