继承默认的压倒一切的嵌套JSON编码支持像字典,列表对象(Overriding nested JSO

2019-09-01 21:42发布

我已经设置了我自己的一些类,是从字典子类 ,像他们。 然而,当我想将它们编码成JSON(使用Python),我希望他们在,我可以回解码为原来的对象,而不是一个字典的方式进行序列化。

所以我要支持我自己的类(即从字典继承)的嵌套对象。

我曾尝试这样的东西:

class ShadingInfoEncoder(json.JSONEncoder):
    def encode(self, o):
        if type(o).__name__ == "NodeInfo":
            return '{"_NodeInfo": ' + super(ShadingInfoEncoder, self).encode(o) + '}'
        elif type(o).__name__ == "ShapeInfo":
            return '{"_ShapeInfo": ' + super(ShadingInfoEncoder, self).encode(o) + '}'
        elif type(o).__name__ == "ShaderInfo":
            return '{"_ShaderInfo": ' + super(ShadingInfoEncoder, self).encode(o) + '}'

        return super(ShadingInfoEncoder, self).encode(o)

和:

class ShadingInfoEncoder(json.JSONEncoder):
    def encode(self, o):
        if isinstance(o, NodeInfo):
            return '{"_NodeInfo": ' + super(ShadingInfoEncoder, self).encode(o) + '}'
        elif isinstance(o, ShapeInfo):
            return '{"_ShapeInfo": ' + super(ShadingInfoEncoder, self).encode(o) + '}'
        elif isinstance(o, ShaderInfo):
            return '{"_ShaderInfo": ' + super(ShadingInfoEncoder, self).encode(o) + '}'

        return super(ShadingInfoEncoder, self).encode(o)

它工作在一般情况下,尚未当它们嵌套或第一个对象被情人抛弃的不是那种类型的。 因此,当输入对象是该类型的这仅适用。 然而,不是当它的嵌套。

我不知道如何将这个JSON递归因此所有的嵌套编码/载情况下按照同样的规则进行编码。

我认为这将是更容易使用JSONEncoder的默认方法(如被调用只要对象是不支持的类型的。)然而,自从我的对象是从字典继承他们得到的“默认”解析,字典而不是过程方法。

Answer 1:

最后我做了以下内容。

class ShadingInfoEncoder(json.JSONEncoder):
    def _iterencode(self, o, markers=None):
        jsonPlaceholderNames = (("_ShaderInfo", ShaderInfo),
                            ("_ShapeInfo", ShapeInfo),
                            ("_NodeInfo", NodeInfo))
        for jsonPlaceholderName, cls in customIterEncode:
            if isinstance(o, cls):
                yield '{"' + jsonPlaceholderName+ '": '
                for chunk in super(ShadingInfoEncoder, self)._iterencode(o, markers):
                    yield chunk
                yield '}'
                break
        else:
            for chunk in super(ShadingInfoEncoder, self)._iterencode(o, markers):
                yield chunk

我想这是不是要做到这一点的最好办法,但我在这里分享它,看看是否有人能告诉我什么,我做错了,并告诉我要做到这一点的最好办法!

请注意,我用的,而不是一本字典嵌套结构,因为我想保持他们上市,所以我可以命令 - 在这个例子中 - 覆盖ShaderInfo成为_NodeInfo如果ShaderInfo是从继承的nodeinfo对象。

我的解码器设置做沿东西线(简化的代码部分):

class ShadingInfoDecoder(json.JSONDecoder):
    def decode(self, obj):
        obj = super(ShadingInfoDecoder,self).decode(s)
        if isinstance(obj, dict):
            decoders = [("_set",self.setDecode),
                        ("_NodeInfo", self.nodeInfoDecode),
                        ("_ShapeInfo", self.shapeInfoDecode),
                        ("_ShaderInfo", self.shaderInfoDecode)]
            for placeholder, decoder in decoders:
                if placeholder in obj:
                    return decoder(obj[placeholder])
                else:
                    for k in obj:
                        obj[k] = self.recursiveDecode(obj[k])
        elif isinstance(obj, list):
            for x in range(len(obj)):
                obj[x] = self.recursiveDecode(obj[x])

        return obj

    def setDecode(self, v):
        return set(v)

    def nodeInfoDecode(self, v):
        o = NodeInfo()
        o.update(self.recursiveDecode(v))
        return o

    def shapeInfoDecode(self, v):
        o = ShapeInfo()
        o.update(self.recursiveDecode(v))
        return o

    def shaderInfoDecode(self, v):
        o = ShaderInfo()
        o.update(self.recursiveDecode(v))
        return o

该nodeInfoDecode方法获取进入字典,并使用它来初始化时生成并返回的nodeinfo对象的值/属性。

更多信息:

另见我的答案如何更改JSON编码行为序列化Python对象?



文章来源: Overriding nested JSON encoding of inherited default supported objects like dict, list