我想将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对象,是不是会更好?


当前回答

数据类向导是一种现代的选项,可以类似地为您工作。它支持自动键大小写转换,如camelCase或TitleCase,这两者在API响应中都很常见。

当将实例转储到dict/JSON时,默认的键转换是camelCase,但这可以很容易地使用主数据类上提供的Meta配置来覆盖。

https://pypi.org/project/dataclass-wizard/

from dataclasses import dataclass

from dataclass_wizard import fromdict, asdict


@dataclass
class User:
    name: str
    age: int
    is_active: bool


data = {
    'name': 'John',
    'age': 30,
    'isActive': True,
}

user = fromdict(User, data)
assert user == User(name='John', age=30, is_active=True)

json_dict = asdict(user)
assert json_dict == {'name': 'John', 'age': 30, 'isActive': True}

设置元配置的例子,当序列化为dict/JSON时,将字段转换为lisp-case:

DumpMeta(key_transform='LISP').bind_to(User)

其他回答

def load_model_from_dict(self, data: dict):
    for key, value in data.items():
        self.__dict__[key] = value
    return self

它帮助返回你自己的模型,从字典中不可预见的变量。

使用json模块(Python 2.6新增)或几乎总是安装的simplejson模块。

这是我的办法。

特性

支持类型提示 如果缺少键则引发错误。 跳过数据中的额外值

import typing

class User:
    name: str
    age: int

    def __init__(self, data: dict):
        for k, _ in typing.get_type_hints(self).items():
            setattr(self, k, data[k])

data = {
    "name": "Susan",
    "age": 18
}

user = User(data)
print(user.name, user.age)

# Output: Susan 18

这里有一个快速而肮脏的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()

因此,我正在寻找一种不需要大量自定义反序列化代码就能解组任意类型(想想数据类的字典,或者数据类数组的字典的字典)的方法。

这是我的方法:

import json
from dataclasses import dataclass, make_dataclass

from dataclasses_json import DataClassJsonMixin, dataclass_json


@dataclass_json
@dataclass
class Person:
    name: str


def unmarshal_json(data, t):
    Unmarhsal = make_dataclass('Unmarhsal', [('res', t)],
                               bases=(DataClassJsonMixin,))
    d = json.loads(data)
    out = Unmarhsal.from_dict({"res": d})
    return out.res


unmarshalled = unmarshal_json('{"1": {"name": "john"} }', dict[str, Person])
print(unmarshalled)

打印:{'1':Person(name='john')}