2017-03-08 259 views
7

我需要将json-string转换为python对象。按对象我的意思是“新”python3对象,如:如何将json转换为对象?

class MyClass(object): 

我发现了几个帮助例如jsonpickle文档。但我发现的所有教程都是先将对象转换为json,然后再向后转换。

我想从Rest-API转换json字符串。

这是我迄今所做的:

import requests 
import jsonpickle 

class Goal(object): 
    def __init__(self): 
     self.GoaldID = -1 
     self.IsPenalty = False 

class Match(object): 
    def __init__(self): 
     self.Goals = [] 

headers = { 
    "Content-Type": "application/json; charset=utf-8" 
} 

url = "https://www.openligadb.de/api/getmatchdata/39738" 

result = requests.get(url=url, headers=headers) 
obj = jsonpickle.decode(result.json) 
print (obj) 

这导致:

TypeError: the JSON object must be str, bytes or bytearray, not 'method' 

这是很清楚,我认为jsonpickle不能将此转换为我的课(进球,比赛),因为我不告诉jsonpickle输出应该在哪个类中转换。问题是我不知道如何告诉jsonpickle从匹配类型转换对象中的JSON?我怎么知道目标列表应该是List<Goal>

+0

'OBJ = jsonpickle.decode(result.content)'=>这会给你的字典。 – falsetru

+0

'obj = result.json()'也会给你一个字典。 – falsetru

回答

6

以下行会给你一个解释:

obj = jsonpickle.decode(result.content) # NOTE: `.content`, not `.json` 

obj = result.json() 

但没有上述会给你想要的东西(Python对象(不dicitonary))。因为从URL的JSON是不jsonpickle.encode编码 - whcih添加额外的信息来生成JSON(类似{"py/object": "__main__.Goal", ....}


>>> import jsonpickle 
>>> class Goal(object): 
...  def __init__(self): 
...   self.GoaldID = -1 
...   self.IsPenalty = False 
... 
>>> jsonpickle.encode(Goal()) 
'{"py/object": "__main__.Goal", "IsPenalty": false, "GoaldID": -1}' 
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
# JSON encoded with jsonpickle.encode (default unpicklable=True) 
# => additional python class information attached 
# => can be decoded back to Python object 
>>> jsonpickle.decode(jsonpickle.encode(Goal())) 
<__main__.Goal object at 0x10af0e510> 


>>> jsonpickle.encode(Goal(), unpicklable=False) 
'{"IsPenalty": false, "GoaldID": -1}' 
# with unpicklable=False (similar output with json.dumps(..)) 
# => no python class information attached 
# => cannot be decoded back to Python object, but a dict 
>>> jsonpickle.decode(jsonpickle.encode(Goal(), unpicklable=False)) 
{'IsPenalty': False, 'GoaldID': -1} 

如果你想要一个实际的Python对象,它是不是字典,即你喜欢dic.Goals.[0].GoalGetterNamedic["Goals"][0]["GoalGetterName"],使用json.loads与object_hook:

import json 
import types  
import requests 

url = "https://www.openligadb.de/api/getmatchdata/39738" 

result = requests.get(url) 
data = json.loads(result.content, object_hook=lambda d: types.SimpleNamespace(**d)) 
# OR data = result.json(object_hook=lambda d: types.SimpleNamespace(**d)) 
goal_getter = data.Goals[0].GoalGetterName 
# You get `types.SimpleNamespace` objects in place of dictionaries 
+0

非常感谢你。因为我不喜欢通过dic访问魔术字符串,最好使用将dic转换为对象的类方法吗? – Sebi

+0

@Sebi,你为什么将字典转换为对象?当我使用Python时,我只是使用字典/列表/ ...而不进行转换。 (我不认为这是一个神奇的字符串访问;;;) – falsetru

+0

@塞比,我没有使用这个,但看看这个:http://jsonmodels.readthedocs.io/en/latest/ – falsetru

5

做哟你的意思是这样吗?

import json 

class JsonObject(object): 

    def __init__(self, json_content): 
     data = json.loads(json_content) 
     for key, value in data.items(): 
      self.__dict__[key] = value  


jo = JsonObject("{\"key1\":1234,\"key2\":\"Hello World\"}") 
print(jo.key1) 

它打印:

1234 
[Finished in 0.4s] 
+0

好方法谢谢:) – Sebi

+0

不客气:) – Den1al