Сериализация пользовательского класса в Python

возник вопрос о сериализации классов, которые я определил. У меня есть несколько классов

class Foo: def __init__(self, x, y): self.x = x, self.y = y def toDict(self): return dict(Foo = dict(x = self.x, y = self.y)) 

то класс, который может содержать несколько Foos, например:

 class Bar: def __init__(self): self.foos = [Foo(a, b), Foo(1, 2)] 

Хотя это грубое упрощение реальной структуры (оно становится намного, гораздо более вложенным, чем это), это довольно приличный обзор. Фактические данные для этого исходят из псевдо-XML-файла без какой-либо реальной структуры, поэтому я написал парсер в соответствии со спецификацией, предоставленной мне, поэтому теперь у меня есть все данные в серии классов, которые я определил, с фактическими состав.

То, что я хочу сделать, это взять эти данные, которые у меня есть, и выплевывать их в JSON, но я действительно не вижу хорошего (я новичок в Python, это мой первый настоящий проект с ним).

Я определил метод в Foo, toDict (), который создает словарь из информации, но это, очевидно, не сработает, как я надеюсь, когда я пытаюсь сериализовать Bar, с несколькими Foos.

У кого-то есть отличный способ сделать это? Это было очень много нон-стоп обучения / codefest в последние несколько дней, и у меня нет идей для этого, что является последней частью проекта. Я знаю о модуле JSON для Python, но это не помогает мне с этой конкретной проблемой получения моих данных в словаре (или что-то подобное), которое я могу передать json.dump ().

Дайте мне знать, если я смогу прояснить ситуацию.

Спасибо, TJ

Несколько комментариев. Первый:

  • xml.dom.minidom – это встроенная реализация DOM на Python. Очевидно, что если файл не является XML, вы не сможете использовать встроенные функции синтаксического анализа, но похоже, что вы все равно создаете древовидную структуру из файла, и в этом случае вы можете также использовать minidom .

Хорошо, отныне я предполагаю, что у вас есть веская причина для написания вашей собственной структуры в стиле дерева вместо использования встроенных функций.

  • Вы уверены, что узлы должны быть классами? Это кажется очень сложной структурой, когда все, что вам действительно нужно, это куча вложенных dict s:

     root = { "foo1": { "bar1": "spam", "bar2": "ham"}, "foo2": { "baz1": "spam", "baz2": "ham"}, } 

    Вы поняли эту идею.

Хорошо, может быть, вы уверены, что вам нужно, чтобы отдельные узлы были классами. В этом случае они должны все наследовать от некоторого класса BaseNode , правильно? В конце концов, это принципиально похожие вещи.

  • В этом случае определите метод BaseNode.serialise который эффективно печатает некоторую информацию о себе, а затем вызывает serialise для всех своих дочерних элементов. Это рекурсивная проблема; вы можете использовать рекурсивное решение, если ваше дерево действительно действительно вложенное.

    Библиотека json позволяет вам подклассифицировать JSONEncoder для этого.

     >>> import json >>> class ComplexEncoder(json.JSONEncoder): ... def default(self, obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... return json.JSONEncoder.default(self, obj) ... >>> dumps(2 + 1j, cls=ComplexEncoder) '[2.0, 1.0]' >>> ComplexEncoder().encode(2 + 1j) '[2.0, 1.0]' >>> list(ComplexEncoder().iterencode(2 + 1j)) ['[', '2.0', ', ', '1.0', ']'] 

Не могу ничего предложить с JSON, но вы можете использовать модуль Pickle для сериализации ваших объектов в двоичном формате.

Вы можете рассмотреть возможность использования пакета jsonpickle — он в основном позволяет конвертировать наиболее подходящие объекты в json.