如何将JSON数据转换为Python对象?

506 投票
32 回答
810367 浏览
提问于 2025-04-16 20:50

我想把JSON数据转换成Python对象。

我从Facebook的API那里收到了JSON数据对象,我想把它们存储到我的数据库里。

我现在在Django(Python)中的视图是这样的(request.POST里包含了JSON):

response = request.POST
user = FbApiUser(user_id = response['id'])
user.name = response['name']
user.username = response['username']
user.save()
  • 这样做没问题,但我该如何处理复杂的JSON数据对象呢?
  • 如果我能把这个JSON对象转换成Python对象,那使用起来不是更方便吗?

32 个回答

146

请查看一下 专门处理 JSON 对象解码 这一部分,内容在 json模块文档中。你可以用它把 JSON 对象解码成特定的 Python 类型。

这里有个例子:

class User(object):
    def __init__(self, name, username):
        self.name = name
        self.username = username

import json
def object_decoder(obj):
    if '__type__' in obj and obj['__type__'] == 'User':
        return User(obj['name'], obj['username'])
    return obj

json.loads('{"__type__": "User", "name": "John Smith", "username": "jsmith"}',
           object_hook=object_decoder)

print type(User)  # -> <type 'type'>

更新

如果你想通过 json 模块访问字典中的数据,可以这样做:

user = json.loads('{"__type__": "User", "name": "John Smith", "username": "jsmith"}')
print user['name']
print user['username']

就像访问普通字典一样。

187

你可以试试这个:

class User():
    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():
    def __init__(self, street, number):
        self.street = street
        self.number = number

    def __str__(self):
        return "{0} {1}".format(self.street, self.number)

class User():
    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)
693

更新

在Python3中,你可以用一行代码来实现,使用的是 SimpleNamespaceobject_hook

import json
from types import SimpleNamespace

data = '{"name": "John Smith", "hometown": {"name": "New York", "id": 123}}'

# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(data, object_hook=lambda d: SimpleNamespace(**d))
print(x.name, x.hometown.name, x.hometown.id)

旧答案(Python2)

在Python2中,你也可以用一行代码来实现,使用的是 namedtupleobject_hook(不过如果有很多嵌套对象的话,这种方法会很慢):

import json
from collections import namedtuple

data = '{"name": "John Smith", "hometown": {"name": "New York", "id": 123}}'

# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(data, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))
print x.name, x.hometown.name, x.hometown.id

或者,为了方便重复使用:

def _json_object_hook(d): return namedtuple('X', d.keys())(*d.values())
def json2obj(data): return json.loads(data, object_hook=_json_object_hook)

x = json2obj(data)

如果你想处理一些不太适合作为属性名的键,可以看看 namedtuplerename 参数

撰写回答