CaptainDriftwood
CaptainDriftwood

Reputation: 5708

Nested object with Decimal data type and json.dumps()

I have a a python object that is a defaultdict that uses a class object as its default value. This class object contains various variables, some of which are Decimal data types, one is a date time data type, and a couple variables are lists that in turn contain objects that have variables as Decimal data types, date time variables, as well as lists that can in turn have further nested objects.

class ReportObject(object):
    def __init__(self):
        self.name = None
        self.amount1 = Decimal(0.00)
        self.amount2 = Decimal(0.00)
        self.amount1_transactions = [] # This list can contain nested objects that inherit from the ReportObject
        self.amount2_transactions = [] # This list can contain nested objects that inherit from the ReportObject
        self.purchaseOrder = {}

    def __str__(self):
        return self.__dict__

    def __repr__(self):
        return str(self.__dict__)

    def __json__(self):
        dt = {}
        for key, value in self.__dict__.items():
            if type(value) == 'list':
                dt_list = list()
                for dt_val in value:
                    dt_list.append(dt_val.__json__())
                dt[key] = dt_list
            else:
                dt[key] = str(value)
        return dt

The data that I'm trying to json.dumps is a defaultdict of these ReportObjects.

When I go to call json.dumps(data, default: lambda o: o.__json__()) the variables that are a list are getting represented as raw strings instead of being an array of the objects in each list. Is there a cleaner way to code this custom JSON Encoding functionality? I couldn't figure out how to implement a solution from subclassing json.JSONEncoder.

Upvotes: 0

Views: 426

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155536

if type(value) == 'list': will never evaluate to true, so you were always executing the else case (which stringified the value, as you observed); type(value) returns the class that value is an instance of, not a string describing it. The test you want is:

if type(value) is list:      # Only allows lists; since types are singletons, use identity test, not equality

or:

if isinstance(value, list):  # Allows list subclasses

Note the lack of quotes around list; that refers to the type, not a string describing it.

Upvotes: 1

Related Questions