gpt4 book ai didi

python - 如何正确地将 JSON 转换为 Python 对象?

转载 作者:太空宇宙 更新时间:2023-11-03 12:07:12 26 4
gpt4 key购买 nike

我想将从网络服务获取的 JSON 解析为对象结构。因此,我正在使用 object_hook 方法实现 json.JSONDecoder 的子类。我还没有找到为给定数据选择正确类的好方法。对于具有相同属性的类,似乎不可能识别出正确的类,因为那需要知道 key 。让我们看一个例子:

我有以下类(class):

class Post:
def __init__(self, title, user=None, group=None):
self.title = title
self.user = user
self.group = group

class Group:
def __init__(self, name):
self.name = name

class User:
def __init__(self, name):
self.name = name

观察到 GroupUser 类具有相同的属性。现在我的 JSONDecoder 看起来像这样:

 class JSONDecoder(json.JSONDecoder):

def __init__(self, encoding="UTF-8"):
json.JSONDecoder.__init__(self, object_hook=self.dict_to_object)

def dict_to_object(self, d):

if "posts" in d:
return d["posts"]
if "title" in d:
if "user" in d:
return Post(d["title"], user=d["user"])
if "group" in d:
return Post(d["title"], group=d["group"])
if "name" in d:
# How to decide if User(d["name"]) or Group(d["name")?
return None
return None

当它看到一个包含键“name”的字典时,它无法决定是创建一个 Group 还是一个 User 对象(因此我返回 None 目前)。

我想解析的 JSON 字符串如下所示:

s = """
{ "posts" : [
{"title" : "Hello World", "user" : {"name" : "uli"}},
{"title" : "Hello Group", "group" : {"name" : "Workgroup"}}
]
}
"""

这应该会生成一个 Post 对象列表,每个对象都有一个标题和一个组或用户。

如何以最好的方式解决这个问题? if 语句在 dict_to_object 中的这种积累真的是可行的方法吗? (由于复杂的嵌套 JSON 结构,实际代码看起来更加困惑。)或者是否有我应该使用的任何其他模式或库? (尽管我更愿意使用标准库。)

最佳答案

在这种情况下,并且 IME 通常使用 JSON 解码,最好在解码时分配给通用字典,不要使用 object_hook,并将创建单个类型化对象推迟到所有解码后的第二遍,当您可以任意检查你正在处理的流和层次结构,即哪个对象是什么的父/子/兄弟。(就像@BrenBam 说的)

使用类方法 make_xyz 函数,而不是构造函数

object_hook 通常看起来很诱人,但很少是您想要的东西。仅仅因为它在那里,它往往是错误的选择。只有当您始终可以 100% 确定每个对象使用哪个类时,这才是正确的选择(即使那样,只有在不传递状态的情况下很容易评估的情况下,即在您的对象钩子(Hook)中编写一个临时解析器),通常元素遵循特定顺序,JSON 永远不会格式错误等。

在这里您遇到了一个普遍问题:在这种特定情况下,看到 {"name": "xyz"} 的构造函数无法知道它是什么类型的 JSON 对象,只能知道父对象其中看到"user"/"group":即可。一种解决方案是将所有类和构造函数重构为类方法make_group()make_user()。但这只是将您的第二次解码传递合并到您的第一次解码传递中,没有特别的原因,给了我们一个巨大的脆弱的 object_hook 函数。 IME 很少是个好主意。

关于python - 如何正确地将 JSON 转换为 Python 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26641006/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com