我想将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对象,是不是会更好?
如果你正在寻找将JSON或任何复杂字典的类型安全反序列化到python类中,我强烈推荐python 3.7+的pydantic。它不仅有一个简洁的API(不需要编写“helper”样板),可以与Python数据类集成,而且具有复杂和嵌套数据结构的静态和运行时类型验证。
使用示例:
from pydantic import BaseModel
from datetime import datetime
class Item(BaseModel):
field1: str | int # union
field2: int | None = None # optional
field3: str = 'default' # default values
class User(BaseModel):
name: str | None = None
username: str
created: datetime # default type converters
items: list[Item] = [] # nested complex types
data = {
'name': 'Jane Doe',
'username': 'user1',
'created': '2020-12-31T23:59:00+10:00',
'items': [
{'field1': 1, 'field2': 2},
{'field1': 'b'},
{'field1': 'c', 'field3': 'override'}
]
}
user: User = User(**data)
要了解更多细节和特性,请查看文档中的pydantic的rational部分。
这里有一个快速而肮脏的json pickle替代方案
import json
class User:
def __init__(self, name, username):
self.name = name
self.username = username
def to_json(self):
return json.dumps(self.__dict__)
@classmethod
def from_json(cls, json_str):
json_dict = json.loads(json_str)
return cls(**json_dict)
# example usage
User("tbrown", "Tom Brown").to_json()
User.from_json(User("tbrown", "Tom Brown").to_json()).to_json()
使用python 3.7,我发现下面的代码非常简单有效。在本例中,将JSON从文件加载到字典中:
class Characteristic:
def __init__(self, characteristicName, characteristicUUID):
self.characteristicName = characteristicName
self.characteristicUUID = characteristicUUID
class Service:
def __init__(self, serviceName, serviceUUID, characteristics):
self.serviceName = serviceName
self.serviceUUID = serviceUUID
self.characteristics = characteristics
class Definitions:
def __init__(self, services):
self.services = []
for service in services:
self.services.append(Service(**service))
def main():
parser = argparse.ArgumentParser(
prog="BLEStructureGenerator",
description="Taking in a JSON input file which lists all of the services, "
"characteristics and encoded properties. The encoding takes in "
"another optional template services and/or characteristics "
"file where the JSON file contents are applied to the templates.",
epilog="Copyright Brown & Watson International"
)
parser.add_argument('definitionfile',
type=argparse.FileType('r', encoding='UTF-8'),
help="JSON file which contains the list of characteristics and "
"services in the required format")
parser.add_argument('-s', '--services',
type=argparse.FileType('r', encoding='UTF-8'),
help="Services template file to be used for each service in the "
"JSON file list")
parser.add_argument('-c', '--characteristics',
type=argparse.FileType('r', encoding='UTF-8'),
help="Characteristics template file to be used for each service in the "
"JSON file list")
args = parser.parse_args()
definition_dict = json.load(args.definitionfile)
definitions = Definitions(**definition_dict)