【发布时间】:2020-03-24 22:55:24
【问题描述】:
总结
我有一个 Python 对象层次结构,我想使用 JSON 序列化(仅通过 https://docs.python.org/3/library/json.html,不使用任何额外的第三方库)。我想排除某些字段/属性/子对象。我发现很难找到一个关于如何实现这一目标的简单答案?
示例
我将有一个派生类实例,结果如下:
class MyItemClass(BaseItemClass):
self.saveThisProperty = 999
self.dontSaveThisProperty = "Something"
self.saveThisObject = ObjectType1()
self.dontSaveThisObject = ObjectType2()
如果我要序列化为 XML,我希望它看起来像
<MyItemClass>
<saveThisProperty>999</saveThisProperty>
<saveThisObject>
...
</saveThisObject>
</MyItemClass>
请注意,我只序列化某些属性/子对象,我确实不想要序列化我的类实例派生自的整个BaseItemClass。
在 XML 中我很好。我知道如何在执行我想要的操作时输出 XML 位,或者输出到最后保存的临时内存文档,或者通过增量方式将单个节点/元素输出到流中。我不必序列化所有内容。例如
xmlStream.writeStartElement("MyItemClass")
xmlStream.writeElementWithValue("saveThisProperty", 999)
xmlStream.writeStartElement("saveThisObject")
...
xmlStream.writeEndElement("saveThisObject")
xmlStream.writeEndElement("MyItemClass")
对于 JSON,我不能这样做,可以吗?我是否必须通过仅将我想要的属性/子对象复制到其中然后 JSON 序列化来创建一些新的“独立”对象层次结构(没有来自 BaseClass 的派生)? p>
我确实看到有json.dump(default = ...),但上面写着:
如果指定,默认应该是一个函数,该函数会为无法序列化的对象调用。它应该返回对象的 JSON 可编码版本
然而,并不是原始对象不能默认被Python->JSON序列化,而是我不想要那种默认的序列化一切行为,我想要我的“选择性”。
【问题讨论】:
-
我认为你对json文档的理解有误:用户定义的不能默认被序列化;你需要为
default提供一个可以序列化它们的实现,并且该实现可以做任何你想做的事情,只要结果可以被序列化。 -
谢谢。您如何为此编写一个
default函数?我的层次结构将很深,并且涉及不同级别的许多对象类。顶级dump()调用将没有可用的函数/类,它可能知道它将遇到的类,编码需要在遇到时委托给每个类...? -
您可以给每个类一个
serialise方法来产生所需的输出,并让default在它遇到的每个对象上调用obj.serialise(),或者使用像在答案,或棉花糖等。 -
@snakecharmerb 我们快到了!这就是我目前正在做的事情。问题是:我是(a)通过调用
serialise()的树来构建一个新的“影子,可序列化”单对象树,然后在最后传递给json.dump(),还是(b)每个对象的serialise()方法不返回任何内容,而是将序列化写入流,在这种情况下如何? -
每个对象的
serialise方法应该返回一个dict。json.dumps将访问对象图中的所有对象并尝试序列化它们,如果它不知道如何序列化对象,则调用default。你可以写default以便调用serialise是一个包罗万象的,即没有isinstance检查
标签: python json serialization