在 python 中加载 JSON 作为实际对象,而不是 dict [重复]

Posted

技术标签:

【中文标题】在 python 中加载 JSON 作为实际对象,而不是 dict [重复]【英文标题】:Load JSON in python as actual object, not a dict [duplicate] 【发布时间】:2013-10-28 12:33:46 【问题描述】:

是否可以在 python 中使用json.loads() 来创建实际的 Python 对象而不是 dict 值?

我宁愿不用json_data['value_name'],只需要json_object.my_value

【问题讨论】:

你有这方面的实际用例吗?目前,您的问题就像“我更喜欢查看属性访问而不是 dict 查找” - 在这种情况下,答案是,只需使用字典。如果您确实有用例,答案可能取决于它;但是使用setattr... 可以轻松地解决这个问题 【参考方案1】:

您可以使用 Python 替代语法来创建类型:

attributes = 
    'a': 12,
    'b': 'there-is-a-value-here',
    'greet': (lambda self: print("Hi, my a is ".format(self.a)))

SomeCoolType = type("SomeCoolType", (), attributes)
someCoolInstance = SomeCoolType()
someCoolInstance.greet() # this prints "Hi, my a is 12"

第一个参数是类型名称,第二个是带有父类的元组,第三个是属性字典。因此,考虑到这一点,您可以首先将 JSON 解码为 dict,然后从中构造一个类型,然后实例化它:

d = json.loads(json_data)
T = type("JSON", (), d)
json_object = T()

或者,更短:

json_object = type("JSON", (), json.loads(json_data))()

这种简单的方法只会将***字典更改为对象;如果你想能够调用json_object.param.something.value,你必须通过递归来转换它(类似于浅拷贝和深拷贝):

def to_object(dictionary):
    for key, value in dictionary.items():
        if isinstance(value, dict): dictionary[key] = value
    return type("JSON", (), dictionary)

json_object = to_object(json.loads(json_data))

【讨论】:

投反对票 - 您正在动态创建新类并滥用类属性来存储数据(这很糟糕,因为您 #1 为每个 JSON 对象创建一个类,而 #2 每次都浪费时间属性查找,因为它不是实例属性;此外,如果 json 数据包含 "__init__""__new__" 之类的键,这将非常糟糕。一个更好更简单的方法是使用一个类,该类在其__init__ 中使用字典,并使用setattr 创建实例属性,或者只存储字典并覆盖__getattr__ 以访问它。

以上是关于在 python 中加载 JSON 作为实际对象,而不是 dict [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中加载 JSON 代码的问题

在 ExtJS4 TreeGrid 中加载嵌套的 JSON 数据

无法在python中加载json文件[重复]

如何在 appsettings.json 中加载多态对象

如果在 JSON 对象中加载空图像 URL,则应用程序崩溃

如何在 Javascript 中加载本地 JSON 文件