如何将 json 转换为对象?
How to convert json to object?
我需要将 json 字符串转换为 python 对象。我所说的对象是指 "new" python3 个对象,如:
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 无法将其转换为我的 classes(目标,比赛),因为我没有告诉 jsonpickle 在哪个class 应转换输出。问题是我不知道如何告诉 jsonpickle 将对象中的 JSON 从 Match 类型转换?我怎么知道目标列表应该是 List<Goal>
类型?
以下几行将为您提供字典:
obj = jsonpickle.decode(result.content) # NOTE: `.content`, not `.json`
obj = result.json()
但是上面的 none 会给你你想要的(python 对象(不是词典))。因为 url 中的 json 未使用 jsonpickle.encode
编码 - 这会将附加信息添加到生成的 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].GoalGetterName
而不是 dic["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
你的意思是这样的吗?
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]
最近 python 版本的一个干净的方法可能是使用 marshmallow-dataclass :
from dataclasses import field
from marshmallow_dataclass import dataclass
from typing import List
@dataclass
class Goal:
GoaldID: int = field(default=-1)
IsPenalty: bool = field(default=False)
@dataclass
class Match:
Goals: List[Goal] = field(default_factory=lambda: [])
my_match, _ = Match.Schema().load(result.json())
我需要将 json 字符串转换为 python 对象。我所说的对象是指 "new" python3 个对象,如:
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 无法将其转换为我的 classes(目标,比赛),因为我没有告诉 jsonpickle 在哪个class 应转换输出。问题是我不知道如何告诉 jsonpickle 将对象中的 JSON 从 Match 类型转换?我怎么知道目标列表应该是 List<Goal>
类型?
以下几行将为您提供字典:
obj = jsonpickle.decode(result.content) # NOTE: `.content`, not `.json`
obj = result.json()
但是上面的 none 会给你你想要的(python 对象(不是词典))。因为 url 中的 json 未使用 jsonpickle.encode
编码 - 这会将附加信息添加到生成的 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].GoalGetterName
而不是 dic["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
你的意思是这样的吗?
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]
最近 python 版本的一个干净的方法可能是使用 marshmallow-dataclass :
from dataclasses import field
from marshmallow_dataclass import dataclass
from typing import List
@dataclass
class Goal:
GoaldID: int = field(default=-1)
IsPenalty: bool = field(default=False)
@dataclass
class Match:
Goals: List[Goal] = field(default_factory=lambda: [])
my_match, _ = Match.Schema().load(result.json())