【问题标题】:How to dynamically build a JSON object?如何动态构建 JSON 对象?
【发布时间】: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

【问题讨论】:

    标签: python json


    【解决方案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']
          

          【讨论】:

          猜你喜欢
          • 2021-08-05
          • 2015-11-05
          • 2020-03-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-28
          • 2016-10-02
          • 1970-01-01
          相关资源
          最近更新 更多