2017-03-08 3 views
7

J'ai besoin de convertir une chaîne JSON en objet Python. Je veux dire par objet « nouveau » objet python3 comme:Comment convertir json en objet?

class MyClass(object): 

J'ai trouvé plusieurs aide par exemple sur la documentation jsonpickle. Mais tout ce que j'ai trouvé sont des tutoriels qui convertissent l'objet en json d'abord et après cette conversion en arrière.

Je souhaite convertir une chaîne json à partir d'un Rest-API.

Voici ce que je l'ai fait jusqu'à présent:

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) 

Il en résulte:

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

Il est tout à fait clair pour moi que jsonpickle ne peut pas convertir en mes classes (but, Match), car je ne dis pas à jsonpickle dans quelle classe la sortie doit être convertie. Le problème est que je ne sais pas comment dire jsonpickle pour convertir le JSON en objet de type Match? Et comment puis-je dire que la liste des objectifs devrait être de type List<Goal>?

+0

'obj = jsonpickle.decode (result.content)' => Cela vous donnera un dictionnaire. – falsetru

+0

'obj = result.json()' vous donnera également un dictionnaire. – falsetru

Répondre

6

Les lignes suivantes vous donnera un dictionnaire:

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

obj = result.json() 

Mais aucun d'entre ci-dessus vous donnera ce que vous voulez (objet python (non dicitonary)). parce que le JSON de l'URL est pas codé avec jsonpickle.encode - whcih ajouter des informations supplémentaires à un JSON généré (quelque chose comme {"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} 

Si vous voulez un objet Python réel qui n'est pas un dictionnaire , à savoir que vous préférez dic.Goals.[0].GoalGetterName-dic["Goals"][0]["GoalGetterName"], utilisez json.loads avec 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

Ok merci beaucoup. Parce que je n'aime pas l'accès à la chaîne magique via dic, est-il préférable d'utiliser une méthode de classe qui convertit un dic en objet? – Sebi

+0

@Sebi, Pourquoi convertissez-vous le dict en un objet? J'ai juste utilisé le dictionnaire/liste/... sans convertir quand j'utilisais Python. (Je ne pense pas que ce soit un accès à une chaîne magique ;;;) – falsetru

+0

@Sebi, je ne l'ai pas utilisé, mais vérifiez ceci: http://jsonmodels.readthedocs.io/en/latest/ – falsetru

5

Do yo Tu veux dire quelque chose comme ça?

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) 

qui imprime:

1234 
[Finished in 0.4s] 
+0

Bonne approche merci :) – Sebi

+0

Vous êtes les bienvenus :) – Den1al