首页 > 解决方案 > 如何对自定义迭代进行 json 序列化?

问题描述

我想创建一种行为类似于命名元组的类型,除了它具有自定义表示形式,当序列化为 JSON 时也会受到尊重。

天真的书本方法是这样的:

from typing import NamedTuple
import json


class MyPair(NamedTuple):
    left: str
    right: str

    def __repr__(self):
        return self.left + ':' + self.right


class MyJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, MyPair):
            return str(obj)
        return json.JSONEncoder.default(self, obj)

现在print(MyPair('a', 'b'))将按预期输出a:b,但print(json.dumps([MyPair('a', 'b')], cls=MyJSONEncoder))将产生[["a", "b"]]因为default()仅当对象不能原始序列化为 JSON 时才调用。由于我自己的类型是一个元组,它会在我有机会干预之前被序列化。

在用字符串替换所有对象的预处理步骤中,是否有任何好的或不太好的方法来实现这一点,而MyPair不是不做Tuple或迭代整个文档?MyPair

编辑:为了解决 Joran 的回答,我仍然希望保留序列化仅包含偶尔MyPairs 的复杂树的能力。抱歉,我的最小示例可能没有说清楚。

标签: pythonjsonpython-3.xtypes

解决方案


只包含默认参数

def my_class_encoder(o):
    if isinstance(o,MyClass):
       return repr(o)

json.dumps(myClassInstance,default=my_class_encoder)

它比真正的编码器更容易处理

……

但实际上只是在您的课程中添加一个 def

class MyPair(NamedTuple):
    left: str
    right: str
    def serialize(self):
        return list(self)
    def __repr__(self):
        return self.left + ':' + self.right

然后就

 json.dumps(myClassInstance.serialize())

这样做的好处是更清楚它在做什么(至少恕我直言)


推荐阅读