Еще раз про JSON
Для создания кастомной сериализации объектов в JSON не обязательно создавать класс-сериализатор. Достаточно указать функцию default() которую в свою очередь подать в виде лямбды.
За читаемость примера не ручаюсь но выйдет что-то вроде такого:
json.dumps(my_data, default=lambda obj: {
'type': f'{obj.__class__.__module__}.{obj.__class__.__name__}',
'data': getattr(obj, '__dict__', repr(obj))})
В примере я добавил полный путь к классу включая имя модуля.
⚠️ Повторяю! В ситуации, когда данные неизвестны, такой подход может привести к непредсказуемому поведению! Лично я использовал его только для дебага, когда требовалось получить хоть что-то в виде JOSN а не ошибку.
Явное лучше чем неявное 😉
Кстати, обычная функция часто лучше чем лямбда 😬
Так что вам эта же функция в нормальном виде
def default_hook(obj):
return {
'type': f'{obj.__class__.__module__}.'
f'{obj.__class__.__name__}',
'data': getattr(obj, '__dict__', repr(obj))
}
json.dumps(my_data, default=default_hook)
Почему бы не организовать поддержку всех стандартных объектов Python в стандартном JSON-энкодере? Я думаю дело в неочевидности этого процесса. Как можно сериализовать float? Тут вполне очевидно. А как сериализовать datetime? Вот тут тысяча и один вариант как можно форматировать дату. Поэтому данный этап отадётся на откуп разработчику.
Меня устроило бы добавление в спецификацию класса метода __json__ по аналогии с __fspath__, который использовался бы стандартным энкодером. Метод возвращал бы поддерживаемый для JSON объект. Тогда не требуется что-то указывать в функции dump() и наш класс может использоваться в других модулях, где код уже записан и вставить что-то в default м не можем.
Но пока этого нет (и будет ли?) мы по-прежнему добавляем в класс метод toJson() и вызываем его, отправляя в json.dump().
#tricks#libs