我已经设置了我自己的一些类,是从字典子类 ,像他们。 然而,当我想将它们编码成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的默认方法(如被调用只要对象是不支持的类型的。)然而,自从我的对象是从字典继承他们得到的“默认”解析,字典而不是过程方法。
最后我做了以下内容。
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