2017-03-08 161 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