Сериализация списка объектов Python в JSON - PullRequest
0 голосов
/ 18 декабря 2018

Я искал сообщения SO, но не мог найти решение моей проблемы.Я видел кучу SO сообщений, в которых объясняется, как сериализовать объекты Python, не нашел ничего, что объясняет, как сериализовать словарь списка объектов Python.

Вот формулировка проблемы и пример использования:

import json  
import collections    
from collections import defaultdict     

class A:
    def __init__(self, a1_list=[], a2_str=None):
        self.a1_list  = []
        self.a2_str = a2_str

class B:
     def __init__(self, list_of_A_objects=[], b2_str=None):
        self.list_of_A_objects = list_of_A_objects
        self.b2_str = b2_str

if __name__ == "__main__":
     a1 = A([1, 2, 3], '123')
     a2 = A([4, 5, 6], '456')
     b1 = B([a1, a2], '123-456')

     a3 = A([11, 22, 33], '112233')
     a4 = A([44, 55, 66], '445566')
     b2 = B([a3, a4], '112233-445566')

     dict_b = defaultdict(list)
     dict_b['b'].append(b1)
     dict_b['b'].append(b2)
     json.dumps(dict_b) 

В последней строке выдается ошибка json.dumps(dict_b), говорящая

TypeError: Объект типа'B' не JSON-сериализуемый

РЕДАКТИРОВАТЬ:

Я пробовал pickle, как предложил @coldspeed в комментариях, но я 'Я хотел бы просмотреть дамп JSON с помощью текстового редактора.Если я использую pickle, я не могу просмотреть его, поскольку он выгружается в двоичном формате.

Я что-то делаю неправильно?

1 Ответ

0 голосов
/ 18 декабря 2018

Вы можете определить метод для выгрузки вашего classe в json с помощью json.dumps.

import json  
from collections import defaultdict

class A:
    def __init__(self, items=[], string=None):
        self.items = items
        self.string = string

    def toJSON(self):
        return json.dumps(self, default=lambda obj: obj.__dict__)#, sort_keys=True, indent=4)


if __name__ == "__main__":
    a1 = A([1, 2, 3], '123')
    a2 = A([4, 5, 6], '456')
    b1 = A([a1, a2], '123-456')
    print(b1.toJSON())
    # Result: {"items": [{"items": [1, 2, 3], "string": "123"}, {"items": [4, 5, 6], "string": "456"}], "string": "123-456"}

    a3 = A([11, 22, 33], '112233')
    a4 = A([44, 55, 66], '445566')
    b2 = A([a3, a4], '112233-445566')

    dict_b = defaultdict(list)
    dict_b['b'].append(b1.toJSON())
    dict_b['b'].append(b2.toJSON())
    print(json.dumps(dict_b))

Недостатки У вас всегда будет сериализованная версия вашего класса.Чтобы избежать этого побочного эффекта, вы можете установить новый метод, чтобы превратить его в dict с loads

def to_dict(self):
    return json.loads(self.toJSON())

И по умолчанию добавьте object.to_dict

dict_b = defaultdict(list)
dict_b['b'].append(b1.to_dict())
dict_b['b'].append(b2.to_dict())
print(json.dumps(dict_b))
...