如何将JSON数据转换为Python obj

2024-04-26 01:32:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用Python将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对象以便于使用,不是更好吗?


Tags: 数据对象djangoname视图apiid数据库
3条回答

您可以使用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)

如果您希望它处理不好的属性名的键,请检查namedtuple^{} parameter

这不是代码高尔夫,但这是我最简单的技巧,使用^{}作为JSON对象的容器。

与领先的namedtuple解决方案相比,它是:

  • 可能更快/更小,因为它没有为每个对象创建类
  • 更短
  • 没有rename选项,并且可能对不是有效标识符的键有相同的限制(在封面下使用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)

查看jsonmodule documentation中标题为专门化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']

就像一本普通的字典。

相关问题 更多 >