Вложенный объект с типом данных Decimal и json.dumps () - PullRequest
0 голосов
/ 03 января 2019

У меня есть объект python, defaultdict, который использует объект класса в качестве значения по умолчанию. Этот объект класса содержит различные переменные, некоторые из которых являются Decimal типами данных, одна является типом данных даты и времени, а пара переменных представляет собой списки, которые в свою очередь содержат объекты, которые имеют переменные типа Decimal типов данных, переменных времени и даты, а также списки, которые в свою очередь могут иметь дополнительные вложенные объекты.

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

Данные, которые я пытаюсь json.dumps, представляют собой defaultdict из этих ReportObjects.

Когда я вызываю json.dumps(data, default: lambda o: o.__json__()), переменные, представляющие собой список, представляются в виде необработанных строк, а не в виде массива объектов в каждом списке. Есть ли более чистый способ кодирования этой пользовательской функциональности JSON Encoding? Я не мог понять, как реализовать решение на основе подклассов json.JSONEncoder.

1 Ответ

0 голосов
/ 03 января 2019

if type(value) == 'list': никогда не будет иметь значение true, поэтому вы всегда выполняли случай else (который, как вы заметили, строковый value); type(value) возвращает класс, экземпляром которого является value, а не строка, описывающая его. Вы хотите тест :

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

или

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

Обратите внимание на отсутствие кавычек вокруг list; который ссылается на тип, а не на строку, описывающую его.

...