1

I've read through a few questions that address something similar, but wanted to ask about this.

I have two Python classes, simplified here:

class Service:
    def __init__(self):
        self.ServiceName = None
        self.ServiceExpDate = None

class Provision:
    def __init__(self):
        self.ID = None
        self.Type = None
        self.Services = [] # a list of Service objects

When I go to JSON encode an instance of the Provision class:

jsonProvision = json.dumps(provision.__dict__)

I get the correct output if I don't have any Services, but if it tries to serialize the Service class I get:

TypeError: <common.Service instance at 0x123d7e8> is not JSON serializable

Do I need to write a JSON encoder to handle this directly, or is there a better way to serialize the Service class?

Thanks!

2 Answers 2

1

You should write an encoder that takes care of your classes, that's the way json module is meant to be used/extended.

Your attempt to encode the __dict__ of your Provision class instances may work now but is really not future proof if you class evolves.

Sign up to request clarification or add additional context in comments.

Comments

1

You need to provide a function to encode your custom classes as the default parameter to json.dumps(). Example code for the classes:

import json

class JSONEncodable(object):
    def json(self):
        return vars(self)

class Service(JSONEncodable):
    def __init__(self):
        self.ServiceName = None
        self.ServiceExpDate = None

class Provision(JSONEncodable):
    def __init__(self):
        self.ID = None
        self.Type = None
        self.Services = [] # a list of Service objects

Example usage:

>>> from operator import methodcaller
>>> p = Provision()
>>> p.Services.append(Service())
>>> print json.dumps(p, default=methodcaller("json"))
{"Services": [{"ServiceName": null, "ServiceExpDate": null}], "Type": null, "ID": null}

You could also use default=attrgetter("__dict__") to avoid the need for a json() method on every class, but the above approach is more flexible.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.