HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythonCriticalCanonical

How to make a class JSON serializable

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
howserializableclassmakejson

Problem

How to make a Python class serializable?

class FileItem:
    def __init__(self, fname):
        self.fname = fname


Attempt to serialize to JSON:

>>> import json
>>> x = FileItem('/foo/bar')
>>> json.dumps(x)
TypeError: Object of type 'FileItem' is not JSON serializable

Solution

Do you have an idea about the expected output? For example, will this do?

>>> f  = FileItem("/foo/bar")
>>> magic(f)
'{"fname": "/foo/bar"}'


In that case you can merely call json.dumps(f.__dict__).

If you want more customized output then you will have to subclass JSONEncoder and implement your own custom serialization.

For a trivial example, see below.

>>> from json import JSONEncoder
>>> class MyEncoder(JSONEncoder):
        def default(self, o):
            return o.__dict__
    
>>> MyEncoder().encode(f)
'{"fname": "/foo/bar"}'


Then you pass this class into the json.dumps() method as cls kwarg:

json.dumps(cls=MyEncoder)


If you also want to decode then you'll have to supply a custom object_hook to the JSONDecoder class. For example:

>>> def from_json(json_object):
        if 'fname' in json_object:
            return FileItem(json_object['fname'])
>>> f = JSONDecoder(object_hook = from_json).decode('{"fname": "/foo/bar"}')
>>> f

>>>

Code Snippets

>>> f  = FileItem("/foo/bar")
>>> magic(f)
'{"fname": "/foo/bar"}'
>>> from json import JSONEncoder
>>> class MyEncoder(JSONEncoder):
        def default(self, o):
            return o.__dict__
    
>>> MyEncoder().encode(f)
'{"fname": "/foo/bar"}'
json.dumps(cls=MyEncoder)
>>> def from_json(json_object):
        if 'fname' in json_object:
            return FileItem(json_object['fname'])
>>> f = JSONDecoder(object_hook = from_json).decode('{"fname": "/foo/bar"}')
>>> f
<__main__.FileItem object at 0x9337fac>
>>>

Context

Stack Overflow Q#3768895, score: 738

Revisions (0)

No revisions yet.