我想将JSON数据转换为Python对象。
我从Facebook API收到JSON数据对象,我想将其存储在数据库中。
我的当前视图在Django (Python)(请求。POST包含JSON):
response = request.POST
user = FbApiUser(user_id = response['id'])
user.name = response['name']
user.username = response['username']
user.save()
这很好,但是如何处理复杂的JSON数据对象呢?
如果我能以某种方式将这个JSON对象转换为易于使用的Python对象,是不是会更好?
Dacite也可能是您的解决方案,它支持以下功能:
嵌套结构
(基本)类型检查
可选字段(即typing.Optional)
工会
向前引用
集合
自定义类型钩子
https://pypi.org/project/dacite/
from dataclasses import dataclass
from dacite import from_dict
@dataclass
class User:
name: str
age: int
is_active: bool
data = {
'name': 'John',
'age': 30,
'is_active': True,
}
user = from_dict(data_class=User, data=data)
assert user == User(name='John', age=30, is_active=True)
你可以试试这个:
class User(object):
def __init__(self, name, username):
self.name = name
self.username = username
import json
j = json.loads(your_json)
u = User(**j)
只需创建一个新对象,并将参数作为映射传递。
你也可以有一个带有对象的JSON:
import json
class Address(object):
def __init__(self, street, number):
self.street = street
self.number = number
def __str__(self):
return "{0} {1}".format(self.street, self.number)
class User(object):
def __init__(self, name, address):
self.name = name
self.address = Address(**address)
def __str__(self):
return "{0} ,{1}".format(self.name, self.address)
if __name__ == '__main__':
js = '''{"name":"Cristian", "address":{"street":"Sesame","number":122}}'''
j = json.loads(js)
print(j)
u = User(**j)
print(u)
这不是代码高尔夫,但这里是我使用类型的最短技巧。SimpleNamespace作为JSON对象的容器。
与namedtuple解决方案相比,它是:
可能更快/更小,因为它没有为每个对象创建一个类
更短的
没有重命名选项,对于不是有效标识符的键可能有相同的限制(在幕后使用setattr)
例子:
from __future__ import print_function
import json
try:
from types import SimpleNamespace as Namespace
except ImportError:
# Python 2.x fallback
from argparse import Namespace
data = '{"name": "John Smith", "hometown": {"name": "New York", "id": 123}}'
x = json.loads(data, object_hook=lambda d: Namespace(**d))
print (x.name, x.hometown.name, x.hometown.id)
如果你使用的是Python 3.5+,你可以使用json来序列化和反序列化到普通的旧Python对象:
import jsons
response = request.POST
# You'll need your class attributes to match your dict keys, so in your case do:
response['id'] = response.pop('user_id')
# Then you can load that dict into your class:
user = jsons.load(response, FbApiUser)
user.save()
你也可以让FbApiUser从jsons继承。JsonSerializable更优雅:
user = FbApiUser.from_json(response)
如果你的类由Python默认类型组成,比如字符串、整数、列表、日期时间等,这些例子就可以工作。不过,jsons lib需要自定义类型的类型提示。