API Navigator Logo

Serializing a Python Object to JSON

Author: Newtum

This guide demonstrates how to convert a custom Python object into a JSON string. The `json` module doesn't know how to encode custom objects by default, so we need to provide a way to do so.

The `TypeError` Problem

If you try to serialize a custom object directly with `json.dumps()`, you will get a `TypeError` because the JSON encoder only knows how to handle standard Python types.

import json

class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email

user = User("Heidi", "heidi@example.com")

try:
    json_string = json.dumps(user)
except TypeError as e:
    print(f"Error: {e}")

Solution 1: Using a `default` function

You can pass a function to the `default` parameter of `json.dumps()`. This function will be called for objects that can't otherwise be serialized. It should return a serializable version of the object.

import json

class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email

def user_serializer(obj):
    if isinstance(obj, User):
        return {'name': obj.name, 'email': obj.email}
    raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")

user = User("Ivan", "ivan@example.com")
json_string = json.dumps(user, default=user_serializer, indent=2)
print(json_string)

Solution 2: Subclassing `JSONEncoder`

For more complex or reusable serialization logic, you can subclass `json.JSONEncoder` and override its `default()` method.

import json

class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email

class UserEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, User):
            return {'name': obj.name, 'email': obj.email, '_type': 'User'}
        # Let the base class default method raise the TypeError
        return super().default(obj)

user = User("Judy", "judy@example.com")
json_string = json.dumps(user, cls=UserEncoder, indent=2)
print(json_string)