如何动态构建 JSON 对象?

Posted

技术标签:

【中文标题】如何动态构建 JSON 对象?【英文标题】:How to dynamically build a JSON object? 【发布时间】:2014-05-31 09:09:21 【问题描述】:

我是 Python 新手,我正在使用 JSON 数据。我想通过向现有 JSON 对象添加一些键值来动态构建 JSON 对象。

我尝试了以下方法,但得到了TypeError: 'str' object does not support item assignment

import json

json_data = json.dumps()
json_data["key"] = "value"

print 'JSON: ', json_data

【问题讨论】:

【参考方案1】:

将对象编码为 JSON 字符串之前构建对象:

import json

data = 
data['key'] = 'value'
json_data = json.dumps(data)

JSON是一种序列化格式,文本数据代表一种结构。它本身并不是那种结构。

【讨论】:

您的解决方案对我来说就像一个魅力。不过,我无法理解您最后一行的含义,请您详细说明一下。谢谢。 @akki:OP 试图将 JSON 字符串(编码对象的一系列字符)视为对象本身。他们尝试使用json_data['key'] = 'value',但它不起作用,因为json_data 不是Python 字典。 给定一个对象,是否可以自动将对象转换为 JSON 或字典? @CharlieParker:这太宽泛了。 Python 对象并没有简单地反映到 JSON 中,因为 JSON 是一种非常有限的格式,只有少数数据类型。这里有很多关于 SO 的问题已经涵盖了 specific 对象类型和 JSON,例如 Django 或 SQLAlchemy 模型等。 @AlexJohnson:pip list 给你同样的信息并且可以输出 JSON:pip list --format=json【参考方案2】:

已经提供了一个解决方案,它允许构建字典(或用于更复杂数据的嵌套字典),但如果您希望构建一个对象,那么也许可以尝试“ObjDict”。这可以更好地控制要创建的 json,例如保留顺序,并允许构建为可能是您的概念的首选表示的对象。

pip 先安装 objdict。

from objdict import ObjDict

data = ObjDict()
data.key = 'value'
json_data = data.dumps()

【讨论】:

这正是我想要的!鉴于 dicts 是无序的,尽管您可以在调用 json.dumpsjson.dumps(response, sort_keys=True, indent=4) 时按字母顺序排序,但是您会被字母顺序而不是您喜欢的排序、分组和表示形式所困扰【参考方案3】:

你可以在一行中创建 Python 字典并将其序列化为 JSON,它甚至不丑。

my_json_string = json.dumps('key1': val1, 'key2': val2)

【讨论】:

【参考方案4】:

你可以使用EasyDict(doc):

EasyDict 允许将 dict 值作为属性访问(递归工作​​)。 python dicts 的类似 javascript 的属性点表示法。

用途

>>> from easydict import EasyDict as edict
>>> d = edict('foo':3, 'bar':'x':1, 'y':2)
>>> d.foo
3
>>> d.bar.x
1

>>> d = edict(foo=3)
>>> d.foo
3

[安装]:

pip install easydict

【讨论】:

Benyamin,您能否编辑您的示例以显示 JSON 转储和加载的用法?【参考方案5】:

所有之前的答案都是正确的,这里有一种更简单的方法。例如,创建一个 Dict 数据结构来序列化和反序列化一个对象

注意在python中None is Null,我特意用它来演示如何存储null并将其转换为json null)

import json
print('serialization')
myDictObj =  "name":"John", "age":30, "car":None 
##convert object to json
serialized= json.dumps(myDictObj, sort_keys=True, indent=3)
print(serialized)
## now we are gonna convert json to object
deserialization=json.loads(serialized)
print(deserialization)

【讨论】:

【参考方案6】: json.loads 将字符串作为输入并返回字典作为输出。 json.dumps 将字典作为输入并返回一个字符串作为输出。

如果您需要将 JSON 数据转换为 python 对象,可以使用Python3 完成,无需额外安装,使用SimpleNamespaceobject_hook

从字符串

import json
from types import SimpleNamespace

string = '"foo":3, "bar":"x":1, "y":2'

# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(string, object_hook=lambda d: SimpleNamespace(**d))

print(x.foo)
print(x.bar.x)
print(x.bar.y)

输出:

3
1
2

来自文件:

JSON 对象:data.json


    "foo": 3,
    "bar": 
        "x": 1,
        "y": 2
    

import json
from types import SimpleNamespace

with open("data.json") as fh:
    string = fh.read()

# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(string, object_hook=lambda d: SimpleNamespace(**d))

print(x.foo)
print(x.bar.x)
print(x.bar.y)

输出:

3
1
2

来自请求

import json
from types import SimpleNamespace
import requests

r = requests.get('https://api.github.com/users/MilovanTomasevic')

# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(r.text, object_hook=lambda d: SimpleNamespace(**d))

print(x.name)
print(x.company)
print(x.blog)

输出:

Milovan Tomašević
NLB
milovantomasevic.com

如需更美观、更快速地从 API 访问 JSON 响应,请查看this response。

【讨论】:

【参考方案7】:

我创建了一个递归函数来遍历表示 json 结构的嵌套字典。

  myjson=
  myjson["Country"]= "KR":  "id": "220", "name": "South Korea"
  myjson["Creative"]= 
                    "1067405": 
                        "id": "1067405",
                        "url": "https://cdn.gowadogo.com/559d1ba1-8d50-4c7f-b3f5-d80f918006e0.jpg"
                    ,
                    "1067406": 
                        "id": "1067406",
                        "url": "https://cdn.gowadogo.com/3799a70d-339c-4ecb-bc1f-a959dde675b8.jpg"
                    ,
                    "1067407": 
                        "id": "1067407",
                        "url": "https://cdn.gowadogo.com/180af6a5-251d-4aa9-9cd9-51b2fc77d0c6.jpg"
                    
                
   myjson["Offer"]= 
                    "advanced_targeting_enabled": "f",
                    "category_name": "E-commerce/ Shopping",
                    "click_lifespan": "168",
                    "conversion_cap": "50",
                    "currency": "USD",
                    "default_payout": "1.5"
                

   json_data = json.dumps(myjson)

   #reverse back into a json

   paths=[]
   def walk_the_tree(inputDict,suffix=None):
       for key, value in inputDict.items():
            if isinstance(value, dict):
                if suffix==None:
                    suffix=key
                else:
                    suffix+=":"+key

                walk_the_tree(value,suffix)
            else:
                paths.append(suffix+":"+key+":"+value)
 walk_the_tree(myjson)
 print(paths)  

 #split and build your nested dictionary
 json_specs = 
 for path in paths:
     parts=path.split(':')
     value=(parts[-1])
     d=json_specs
     for p in parts[:-1]:
         if p==parts[-2]:
             d = d.setdefault(p,value)
         else:
             d = d.setdefault(p,)
    
 print(json_specs)        

 Paths:
 ['Country:KR:id:220', 'Country:KR:name:South Korea', 'Country:Creative:1067405:id:1067405', 'Country:Creative:1067405:url:https://cdn.gowadogo.com/559d1ba1-8d50-4c7f-b3f5-d80f918006e0.jpg', 'Country:Creative:1067405:1067406:id:1067406', 'Country:Creative:1067405:1067406:url:https://cdn.gowadogo.com/3799a70d-339c-4ecb-bc1f-a959dde675b8.jpg', 'Country:Creative:1067405:1067406:1067407:id:1067407', 'Country:Creative:1067405:1067406:1067407:url:https://cdn.gowadogo.com/180af6a5-251d-4aa9-9cd9-51b2fc77d0c6.jpg', 'Country:Creative:Offer:advanced_targeting_enabled:f', 'Country:Creative:Offer:category_name:E-commerce/ Shopping', 'Country:Creative:Offer:click_lifespan:168', 'Country:Creative:Offer:conversion_cap:50', 'Country:Creative:Offer:currency:USD', 'Country:Creative:Offer:default_payout:1.5']

【讨论】:

查看嵌套字典的反向路径 (***.com/questions/2738141/…)

以上是关于如何动态构建 JSON 对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中构建动态列表?

从Javascript动态构建JSON对象列表[重复]

在 Swift 中动态构建 JSON

如何在 Vue 中从 JSON 构建动态 HTML 控件?

如何使用 JSON 输入构建动态 SQL“WHERE”语句

如何针对 JSON 列构建动态 SQL where 条件