TGTGInsighttelegram intelligenceLIVE / telegram public index
← Python Заметки

TGINSIGHT SIMILAR POSTS

Најди сличен содржај

Изворен канал @pythonotes · Post #229 · 22 мар.

Иногда хочется чтобы в качестве объекта передачи данных был удобный класс но не хочется (или нет возможности) писать сераиализатор в JSON для него. Идеально было бы сделать класс, который сам умел бы сериализоваться в JSON дефолтным модулем без указания дополнительных сериализаторов. Как это сделать? Стандартный модуль JSON умеет правильно сериализовать стандартные типы. Но нам нужен кастомный класс с удобными методами и свойствами. Ответ очевиден - наследуемся от стандартного типа! В качестве базового типа возьмем словарь. Например, мне нужен класс некоего абстрактного элемента списка с именем и индексом. Тогда реализация может быть такой. class Item(dict): def __init__(self, name, index=0): super().__init__(name=name, index=index) @property def name(self): return self['name'] @name.setter def name(self, value): self['name'] = value @property def index(self): return self['index'] @index.setter def index(self, value): self['index'] = value def __setitem__(self, key, value): if key not in ['index', 'name']: raise KeyError super().__setitem__(key, value) Я добавил два свойства с простым переназначением данных в словарь. Но предполагается, что там будут проверки значений и иные вычисления. Еще хорошо бы добавить методы __str__ и __repr__. >>> it = Item('item name') >>> it.name 'item name' >>> it.index 0 Также можно добавить любые методы классу. Например я переопределил __setitem__ чтобы нельзя было задать иные ключи. >>> it['key'] = 123 KeyError Хотя, можно сделать как-то иначе. К примеру, все отличные от основных ключи записывать в отдельный ключ. def __setitem__(self, key, value): if key not in ['index', 'name']: self['meta'][key] = value else: super(Item, self).setitem(key, value) Ну а главная особенность этого класса в том, что он легко понимается стандартным модулем json (конечно, если значения ключей это тоже стандартные типы или наследованные от них) >>> json.dumps(item) '{"index": 2, "name": "item name"}' Самый очевидный пример, использование в библиотеке requests. Передавая объект в аргумент json, мы не можем повлиять на его сериализацию, то есть добавить класс-сериализатор. Там ожидается готовый словарь или иной совместимый тип. import requests requests.post(url, json=item) А вот так выглядит альтернатива с методом toJson() requests.post(url, data=item.toJson(), headers={'Content-Type': 'application/json'}) А ещё ничто не мешает нам в любой момент конвертнуть наш класс в обычный словарь >>> dict(item) {"index": 2, "name": "item name"} Не спорю, возможно есть более "умные" решения этой задачи 🤓 Но, тем не менее, аналогичным образом работает стандартный collections.namedtuple. Он тоже наследуется от стандартного tuple, расширяет его функционал и сериализуется без дополнительных средств. Для более сложных случаев можно посмотреть на библиотеку dataclasses-json, которая поможет сериализовать dataclasses. #tricks#libs

Hashtags

Резултати

Пронајдени 0 слични објави

Пребарај: #libs

当前筛选 #libs清除筛选

Не се пронајдени слични објави.

Оваа објава нема претходно пресметани резултати на сличност.