У меня есть Python set
, который содержит объекты с __hash__
и __eq__
методов, чтобы не допускать дубликатов в коллекцию.Как сериализовать сериалы JSON?
Мне нужно JSon закодировать этот результат set
, но проходя даже пустой set
к методу json.dumps
поднимает TypeError
.
File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 178, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: set([]) is not JSON serializable
Я знаю, что могу создать расширение для json.JSONEncoder
класса, который имеет метод пользовательского default
, но я даже не знаю, с чего начать в преобразовании над set
. Должен ли я создать словарь из значений set
в методе по умолчанию, а затем вернуть в него кодировку? В идеале я хотел бы, чтобы метод по умолчанию мог обрабатывать все типы данных, которые зажимает оригинальный кодировщик (я использую Mongo в качестве источника данных, поэтому даты также могут вызвать эту ошибку)
Любой намек на правильное направление было бы оценено.
EDIT:
Спасибо за ответ! Возможно, я должен был быть более точным.
Я использовал (и поддержал) ответы здесь, чтобы обойти ограничения перевода set
, но есть и внутренние ключи, которые также являются проблемой.
Объекты в set
являются сложными объектами, которые переводятся на __dict__
, но сами они также могут содержать значения для их свойств, которые могут быть непригодными для основных типов в кодировщике json.
Существует много разных типов, входящих в этот set
, и хеш в основном вычисляет уникальный идентификатор для сущности, но в истинном духе NoSQL не указано точно, что представляет собой дочерний объект.
Один объект может содержать значение даты для starts
, тогда как другой может иметь другую схему, которая не содержит ключей, содержащих «непримитивные» объекты.
Вот почему единственным решением, которое я мог придумать, было расширение JSONEncoder
, чтобы заменить метод default
, чтобы включить разные случаи - но я не уверен, как это сделать, и документация неоднозначна. В вложенных объектах значение, возвращаемое с default
, происходит по ключу, или это просто общий include/discard, который смотрит на весь объект? Как этот метод поддерживает вложенные значения? Я просмотрел предыдущие вопросы и, похоже, не нашел лучшего подхода к кодировке, зависящей от конкретного случая (что, к сожалению, похоже на то, что мне нужно будет делать здесь).
почему 'dict's? Я думаю, что вы хотите сделать только «список» из набора, а затем передать его в кодировщик ... например: 'encode (list (myset))' – Constantinius
Вместо использования JSON вы можете использовать YAML (JSON по существу подмножество YAML). –
@PaoloMoretti: Приносит ли это какое-то преимущество?Я не думаю, что набор относится к универсальным типам данных YAML, и он менее широко поддерживается, особенно в отношении API. – delnan