Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easy JSON encoding with Python

I'm quite new to python (I use python 3), and i'm trying to serialize a class with one string and two lists as members in JSon. I found that there's a json lib in the python standart but it seems that I need to manually implement a serialization method. Is there a JSon encoder where I can simply pass an object, and receive the serialized object as string without having to implement a serialization method. Example:

class MyClass:
    pass

if __name__ == '__main__':
    my_name = "me"
    my_list = {"one","two"}
    my_obj = MyClass()
    my_obj.name = my_name;
    my_obj.my_list = my_list


    serialized_object = JSONserializer.serialize(my_obj).

Thank you.

like image 403
Alexandre Deschamps Avatar asked Sep 09 '10 18:09

Alexandre Deschamps


2 Answers

Don't know of anything pre-built, but you can write one if your objects are simple enough. Override the default method in the JSONEncoder to look at inspect.getmembers(obj) (inspect is a more readable way of getting at sets of attributes in __dict__).

#!/usr/bin/env python3

import inspect
from json import JSONEncoder


class TreeNode:

    def __init__(self, value, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right


class ObjectJSONEncoder(JSONEncoder):

    def default(self, reject):
        is_not_method = lambda o: not inspect.isroutine(o)
        non_methods = inspect.getmembers(reject, is_not_method)
        return {attr: value for attr, value in non_methods
                if not attr.startswith('__')}


if __name__ == '__main__':
    tree = TreeNode(42,
        TreeNode(24),
        TreeNode(242),
    )
    print(ObjectJSONEncoder().encode(tree))

Update: @Alexandre Deschamps says isroutine works better than is method for some input.

like image 188
cdleary Avatar answered Oct 02 '22 13:10

cdleary


How would you expect the json library to know how to serialize arbitrary classes?

In your case, if your class is simple enough, you might be able to get away something like

foo = FooObject() # or whatever
json_string = json.dumps(foo.__dict__)

to just serialize the object's members.

Deserialization would then need to be something like

foo_data = json.loads(json_string)
foo = FooObject(**foo_data)
like image 35
Will McCutchen Avatar answered Oct 02 '22 13:10

Will McCutchen