当前位置: 首页 > 面试题库 >

覆盖继承的默认受支持对象(如dict,list)的嵌套JSON编码

贾兴学
2023-03-14
问题内容

我已经建立了一些 自己的类,这些类从字典中被继承
为类似的类。但是,当我想将它们编码为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对象的值/属性。



 类似资料:
  • 我们正在建立一个服务。它必须从文件中读取config。我们目前正在使用YAML和Jackson来反序列化YAML。我们有一种情况,我们的YAML文件需要继承/扩展另一个(多个)YAML文件。例如,类似于: 因此,部分配置存储在中。是否有任何库对此提供支持?如果它允许从多个文件继承,则会加分。我们可以改为使用JSON而不是YAML。

  • 问题内容: 我一直在阅读道格拉斯·克罗克福德(DouglasCrockford)撰写的“Javascript:好的部分”,尽管有些极端,但我同意他的许多意见。 在第3章中,他讨论了对象,并在某一时刻列出了一种模式,以简化和避免使用内置的“ new”关键字带来的一些混淆/问题。 因此,我尝试在正在处理的项目中使用它,并且在尝试从嵌套对象继承时发现了一个问题。如果我覆盖使用此模式继承的嵌套对象的值,则

  • 我有一个带有嵌套字段的JSON: 我正在使用JSONPATH从嵌套中获取。 我已经将我的JSON文本粘贴到了http://jsonpath.com/这个网站上;并且在使用了这一行之后: 我得到了这个: 使用此行后: 我得到了这个: 我尝试返回(输出)的内容如下: 但是我找不到合适的语法来将这两个组合在一行中,并用一个JSONPATH查询返回它们。

  • 面向对象编程很重要的一个方面,就是对象的继承。A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的。 大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现,本章介绍 JavaScript 的原型链继承。 ES6 引入了 class

  • 问题内容: 我已经能够覆盖所有名称以“ android:”为前缀的主题,但是Android themes.xml还定义了似乎无法被覆盖的属性。例如: colorTheground是在Theme.Light xml中定义的,但是在此处添加它可以使我 错误。如何为整个应用程序覆盖该样式? 问题答案: 您可以用修改属性(如)的方式覆盖标准属性,只是不要忘记添加如下前缀:

  • 问题内容: 我想覆盖Java外观。我只想显示不同的按钮。 我想要Windows Look and Feel的所有功能,但仅按钮有所不同。希望你明白我的意思。 还告诉我如何制作圆形的JtabbedPane ??? 问题答案: 自定义GUI类 调用您的自定义GUI类