Интересные заметки и обучающие материалы по Python
Контакт: @paulwinex
⚠️ Рекламу на канале не делаю!⚠️
Хештеги для поиска:
#tricks
#libs
#pep
#basic
#regex
#qt
#django
#2to3
#source
#offtop
Post #190
1.39K
Еще раз про JSON
Для создания кастомной сериализации объектов в JSON не обязательно создавать класс-сериализатор. Достаточно указать функцию default() которую в свою очередь подать в виде лямбды.
За читаемость примера не ручаюсь но выйдет что-то вроде такого:
⚠️ Повторяю! В ситуации, когда данные неизвестны, такой подход может привести к непредсказуемому поведению! Лично я использовал его только для дебага, когда требовалось получить хоть что-то в виде JOSN а не ошибку.
Явное лучше чем неявное 😉
Кстати, обычная функция часто лучше чем лямбда 😬
Так что вам эта же функция в нормальном виде
Меня устроило бы добавление в спецификацию класса метода
Но пока этого нет (и будет ли?) мы по-прежнему добавляем в класс метод
#tricks #libs
Для создания кастомной сериализации объектов в 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):Почему бы не организовать поддержку всех стандартных объектов Python в стандартном JSON-энкодере? Я думаю дело в неочевидности этого процесса. Как можно сериализовать float? Тут вполне очевидно. А как сериализовать datetime? Вот тут тысяча и один вариант как можно форматировать дату. Поэтому данный этап отадётся на откуп разработчику.
return {
'type': f'{obj.__class__.__module__}.'
f'{obj.__class__.__name__}',
'data': getattr(obj, '__dict__', repr(obj))
}
json.dumps(my_data, default=default_hook)
Меня устроило бы добавление в спецификацию класса метода
__json__ по аналогии с __fspath__, который использовался бы стандартным энкодером. Метод возвращал бы поддерживаемый для JSON объект. Тогда не требуется что-то указывать в функции dump() и наш класс может использоваться в других модулях, где код уже записан и вставить что-то в default м не можем.Но пока этого нет (и будет ли?) мы по-прежнему добавляем в класс метод
toJson() и вызываем его, отправляя в json.dump().#tricks #libs

