Home > database >  json.dumps not working with custom python object
json.dumps not working with custom python object

Time:12-24

I am not able to serialize a custom object in python 3 . Below is the explanation and code

packages= []
data = {
    "simplefield": "value1",
    "complexfield": packages,
}

where packages is a list of custom object Library. Library object is a class as below (I have also sub-classed json.JSONEncoder but it is not helping )

class Library(json.JSONEncoder):
def __init__(self, name):
    print("calling Library constructor ")
    self.name = name

def default(self, object):
    print("calling default method ")
    if isinstance(object, Library):
        return {
            "name": object.name
        }
    else:
        raiseExceptions("Object is not instance of Library")

Now I am calling json.dumps(data) but it is throwing below exception.

TypeError: Object of type `Library` is not JSON serializable 

It seems "calling default method" is not printed meaning, Library.default method is not called

Can anybody please help here ?

I have also referred to Serializing class instance to JSON but its is not helping much

CodePudding user response:

Inheriting json.JSONEncoder will not make a class serializable. You should define your encoder separately and then provide the encoder instance in the json.dumps call.

See an example approach below

import json
from typing import Any


class Library:
    def __init__(self, name):
        print("calling Library constructor ")
        self.name = name

    def __repr__(self):
        # I have just created a serialized version of the object
        return '{"name": "%s"}' % self.name

# Create your custom encoder
class CustomEncoder(json.JSONEncoder):

    def default(self, o: Any) -> Any:
        # Encode differently for different types
        return str(o) if isinstance(o, Library) else super().default(o)


packages = [Library("package1"), Library("package2")]
data = {
    "simplefield": "value1",
    "complexfield": packages,
}
#Use your encoder while serializing
print(json.dumps(data, cls=CustomEncoder))

Output was like:

{"simplefield": "value1", "complexfield": ["{\"name\": \"package1\"}", "{\"name\": \"package2\"}"]}

CodePudding user response:

You can use the default parameter of json.dump:

def default(obj):
  if isinstance(obj, Library):
      return {"name": obj.name}
  raise TypeError(f"Can't serialize {obj!r}.")

json.dumps(data, default=default)
  • Related