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


当前回答

我已经编写了一个名为any2any的小型(反)序列化框架,它可以帮助在两种Python类型之间进行复杂的转换。

在您的情况下,我猜您想从字典(通过json.loads获得)转换为复杂的对象response.education;Response.name,具有嵌套结构response.education.id,等等… 这就是这个框架的用途。文档还不是很好,但是通过使用any2any.simple。MappingToObject,你应该可以很容易地做到。如果需要帮助,请询问。

其他回答

如果你正在使用python 3.6+,你可以使用棉花糖-数据类。与上面列出的所有解决方案相反,它既简单,又类型安全:

from marshmallow_dataclass import dataclass

@dataclass
class User:
    name: str

user = User.Schema().load({"name": "Ramirez"})

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

如果你使用的是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需要自定义类型的类型提示。

已经有多种可行的答案,但有一些由个人制作的小型库可以满足大多数用户的需求。

json2object就是一个例子。给定一个已定义的类,它将json数据反序列化到您的自定义模型,包括自定义属性和子对象。

它的使用非常简单。一个来自图书馆wiki的例子:

从json2object导入jsontoobject作为Jo 类学生: def __init__(自我): 自我。firstName =无 自我。lastName = None 自我。courses =[课程(")] 类课程: 定义__init__(self, name): Self.name = name 数据= " '{ “firstName”:“詹姆斯”, “姓”:“债券”, “课程”:[{ “名称”:“战斗”}, { “名称”:“射击”} ] } “‘ model = Student() Result = jo.deserialize(数据,模型) print (result.courses [0] . name)

你可以使用

x = Map(json.loads(response))
x.__class__ = MyClass

在哪里

class Map(dict):
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    self[k] = v
                    if isinstance(v, dict):
                        self[k] = Map(v)

        if kwargs:
            # for python 3 use kwargs.items()
            for k, v in kwargs.iteritems():
                self[k] = v
                if isinstance(v, dict):
                    self[k] = Map(v)

    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

对于通用的、经得起未来考验的解决方案。