Описывать для каждого отдельный
if isinstance()? А если нам не известно что именно придётся сериализовать и нужно поддерживать в принципе всё что угодно? Ну хотя бы как-то записать объект чтобы не было ошибки и чтобы объект записался в JSON более менее информативно.
В этом случае можно вызвать стандартные способы репрезентации объекта. Самое простое это функция repr(). И тут уж как повезёт с тем, как именно разработчик позаботился о таком поведении его класса.
Более описательный метод, это закинуть объект в словарь с именем класса и данными инстанса.
В общем, возвращаясь к примеру из прошлого поста, мы просто убираем проверку конкретного типа
class MySerializer(json.JSONEncoder):Функция vars() аналогична обращению к атрибуту
def default(self, obj):
return {'type': obj.__class__.__name__,
'data': vars(obj)}
__dict__
Теперь любой ранее неизвестный объект будет успешно сериализован... или нет?>>> json.dumps(datetime.datetime.now(), cls=MySerializer)Так уж вышло, что не любой объект имеет атрибут
AttributeError: 'datetime.datetime' object has no attribute '__dict__
__dict__. В таком случае используем repr()class MySerializer(json.JSONEncoder):То есть мы пробуем забрать данные инстанса, и если не получается то вызываем стандартное строковое представление объекта в надежде что разработчики позаботились о нём.
def default(self, obj):
return {'type': obj.__class__.__name__,
'data': getattr(obj, '__dict__', repr(obj))}
>>> json.dumps(datetime.now(), cls=MySerializer)⚠️ PS: Не могу сказать что решение идеально. Такую неявную сериализацию можно сравнить с замалчиванием ошибок.
'{"type": "datetime", "data": "datetime.datetime(...)"}'
try:То есть в какой-то момент вы будете получать совершенно бесполезные данные и придётся искать где это происходит. Если не определён метод
do_something()
except:
pass
__repr__ то вы получите что-то вроде такого<__main__.MyClass object at 0x00000147CE48CBC8>Что с этим делать? Непонятно! 🤔
Скорее всего найдутся люди, которые осудят такой подход.
Может выбрасывать ошибку в случае отсутствия метода
__repr__ в классе?#libs #tricks