Сериализация пользовательского класса в Python - PullRequest
3 голосов
/ 03 ноября 2010

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

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 ().

Дайте мне знать, если я смогу уточнить каким-либо образом.

Спасибо, T.J.

Ответы [ 3 ]

5 голосов
/ 03 ноября 2010

Несколько комментариев. Во-первых:

  • xml.dom.minidom - это встроенная реализация Python DOM. Очевидно, что если файл на самом деле не является 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', ']']
    
0 голосов
/ 08 июня 2012

Вы можете рассмотреть возможность использования пакета jsonpickle - он в основном позволяет конвертировать большинство объектов, которые можно выбрать в json.

0 голосов
/ 03 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...