How to serialize a list containing class instances?

Viewed 40

How can I serialize an object that contains a list of objects to JSON?

The error I get:

TypeError: Object of type person is not JSON serializable

Code:

import json

class person:
    def __init__(self, name, cars):
        self._name = name
        self._cars = cars
    
class car:
    def __init__(self, brand, color):
        self._brand = brand
        self._color = color

Jason = person("Jason", [car("Toyota", "Blue"), car("Honda", "Red")])
Kenny = person("Kenny", [car("Honda", "Black"), car("Toyota", "Pink")])

json = json.dumps([Jason, Kenny])
print(json)

The output I want :

[
    {
        "name": "Jason",
        "cars":[
            {
                "brand": "Toyota",
                "color": "Blue"
            },
            {
                "brand": "Honda",
                "color": "Red"
            }
        ]
    },
    {
       ...
    }
]
1 Answers

You can create your own json.JSONEncoder and add special method to your classes. For example:

import json


class MyEncoder(json.JSONEncoder):
    def default(self, o):
        if hasattr(o, "reprJson"):
            return o.reprJson()
        else:
            return super().default(o)


class person:
    def __init__(self, name, cars):
        self._name = name
        self._cars = cars

    def reprJson(self):
        return dict(name=self._name, cars=self._cars)


class car:
    def __init__(self, brand, color):
        self._brand = brand
        self._color = color

    def reprJson(self):
        return dict(brand=self._brand, color=self._color)


Jason = person("Jason", [car("Toyota", "Blue"), car("Honda", "Red")])
Kenny = person("Kenny", [car("Honda", "Black"), car("Toyota", "Pink")])

print(json.dumps([Jason, Kenny], cls=MyEncoder, indent=4))

Prints:

[
    {
        "name": "Jason",
        "cars": [
            {
                "brand": "Toyota",
                "color": "Blue"
            },
            {
                "brand": "Honda",
                "color": "Red"
            }
        ]
    },
    {
        "name": "Kenny",
        "cars": [
            {
                "brand": "Honda",
                "color": "Black"
            },
            {
                "brand": "Toyota",
                "color": "Pink"
            }
        ]
    }
]
Related