【问题标题】:Serializing a user-defined class in Python在 Python 中序列化用户定义的类
【发布时间】:2011-05-04 14:11:48
【问题描述】:

有一个关于序列化我定义的类的问题。我有一些课程,例如

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

然后是一个可以包含多个Foo的类,如:

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

虽然这是对真实结构的严重过度简化(它的嵌套程度远不止于此),但这是一个相当不错的概述。实际数据来自一个没有任何实际结构的伪 XML 文件,所以我根据给我的规范编写了一个解析器,所以我现在拥有我定义的一系列类中的所有数据,实际结构。

我想要做的是将我拥有的这些数据吐出到 JSON 中,但我真的没有看到好的方法(我是 Python 新手,这是我第一个真正使用它的项目) .

我在 Foo 中定义了一个方法 toDict(),它根据信息创建一个字典,但是当我尝试使用多个 Foo 序列化 Bar 时,显然不会像我希望的那样工作。

有没有人有这样做的好方法?在过去的几天里,这是一个几乎不间断的学习/代码节,我对此一无所知,这是项目的最后一部分。我知道 Python 的 JSON 模块,但这并不能帮助我解决将数据放入可以传递给 json.dump() 的字典(或类似的东西)的特殊问题。

如果我能以任何方式澄清,请告诉我。

谢谢, T.J.

【问题讨论】:

    标签: python json serialization


    【解决方案1】:

    几个cmets。第一:

    • xml.dom.minidom 是一个内置的 Python DOM 实现。显然,如果文件实际上不是 XML,您将无法使用它的内置解析功能,但看起来您无论如何都在从文件中构建树状结构,在这种情况下,您不妨使用minidom

    好的,以后我假设您有充分的理由编写自己的树形结构而不是使用内置函数。

    • 您确定节点应该是类吗?当你真正需要的只是一堆嵌套的 dicts 时,这似乎是一个非常多的结构:

      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', ']']
      

    【讨论】:

    • 对。该文件最初是一种完全非结构化的格式,但当它到达我的时候,每一行都包含在一个标签中,文件的开头有一个根标签。它实际上不是 XML,而是一些疯狂的过时系统,看起来像 XML。 (此处换行)这些标签中的一些通过它们出现的顺序以及其中包含的数据与其他标签相关。我的解析器所做的是将这些标签分解成它们的实际结构,称为循环,然后我需要将其转换为像 JSON 这样的网络友好格式。
    【解决方案2】:

    无法使用 JSON 提出任何建议,但您可以使用 Pickle 模块以二进制格式序列化您的对象。

    【讨论】:

    • 是的,问题是我需要在网络上使用这些数据,而 JSON 是我希望这样做的方式。
    【解决方案3】:

    您可以考虑使用jsonpickle 包 --- 它基本上允许您将大多数可腌制对象转换为 json。

    【讨论】:

      猜你喜欢
      • 2019-03-02
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      • 2022-07-06
      • 2011-09-06
      • 2019-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多