7

I would like to serialize all objects that have the key "manager_objects" in the following dictionary. What is the easiest way to do so?

department {
id: 1,
name: 'ARC',
manager_object: <Object>
sub_department: {
    id: 5,
    name: 'ABC'
    manager_object: <Object>
    sub_department: {
        id: 7,
        name: 'TRW',
        manager_object: <Object>
        sub_department: {
            id: 9,
            name: 'MYT',
            manager_object: <Object>
            sub_deparment: {
                id: 12,
                name: 'NMY'
                manager_object: <Object>
                sub_department: {}
            }

        }
    }

}

}

1
  • What do you want your resulting JSON to look like? An array of Manager objects? Or are you keeping the sub_departments as well to maintain the structure of the data? Or are you just wondering how to serialize a custom object (the Manager)? Commented Jun 27, 2015 at 4:50

3 Answers 3

5

You can write your own JsonEncoder (or use method described by @PaulDapolito). But, both methods works only if you know type of the item with key manager_object. From docs: To use a custom JSONEncoder subclass (e.g. one that overrides the default() method to serialize additional types), specify it with the cls kwarg; otherwise JSONEncoder is used.

# Example of custom encoder
class CustomJsonEncoder(json.JSONEncoder):
    def default(self, o):
        # Here you can serialize your object depending of its type
        # or you can define a method in your class which serializes the object           
        if isinstance(o, (Employee, Autocar)):
            return o.__dict__  # Or another method to serialize it
        else:
            return json.JSONEncoder.encode(self, o)

# Usage
json.dumps(items, cls=CustomJsonEncoder)
0
4

Nested dictionaries, enum, date, time and datetime are not serializable in Python by default. Here is the way I handle those types

from datetime import time
from datetime import datetime
from datetime import timedelta
import json
import enum

def to_serializable(val):
    """JSON serializer for objects not serializable by default"""

    if isinstance(val, (datetime, date, time)):
        return val.isoformat()
    elif isinstance(val, enum.Enum):
        return val.value
    elif hasattr(val, '__dict__'):
        return val.__dict__

    return val


def to_json(data):
    """Converts object to JSON formatted string"""

    return json.dumps(data, default=to_serializable)

# example on how to serialize dict
to_json(mydict.__dict__)
3

If your dictionary contains objects that Python/json does not know how to serialize by default, you need to give json.dump or json.dumps a function as its default keyword which tells it how to serialize those objects. By example:

import json

class Friend(object):
    def __init__(self, name, phone_num):
        self.name = name
        self.phone_num = phone_num

def serialize_friend(obj):
   if isinstance(obj, Friend):
       serial = obj.name + "-" + str(obj.phone_num)
       return serial
   else:
       raise TypeError ("Type not serializable")

paul = Friend("Paul", 1234567890)
john = Friend("John", 1234567890)

friends_dict = {"paul": paul, "john": john}
print json.dumps(friends_dict, default=serialize_friend)
2
  • This worked like a charm! Thank you! Is there a way to send different functions for the default. Let's say I have two different objects in the dictionary (manager_object and employee_object), can I define two functions and pass them to json.dumps? Commented Jun 27, 2015 at 4:52
  • just check for more object instance in your serialization function. you might say: else if isinstance(obj, employee): serial= .... Commented Jun 27, 2015 at 5:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.