我已经建立了一些 自己的类,这些类从字典中被继承 为类似的类。但是,当我想将它们编码为JSON(使用Python)时,我希望将它们序列化,以便可以将其解码回原始对象,而不是字典。
因此,我想支持我自己的类的嵌套对象(从dict继承)。
我尝试过类似的东西:
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的默认方法会更容易(因为只要对象是不受支持的类型,就会调用该方法。)但是由于我的对象是从dict继承的,因此它们被解析为字典,而不是由“默认”处理方法。
我最终做了以下工作。
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对象的值/属性。