如何将JSON数据转换为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对象以方便使用,会不会更好?

你可以在一行中使用object_hookobject_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参数 。

查看json模块文档( http://docs.python.org/library/json.html for Python v2.7.3)中标记为“专业化JSON对象解码”的部分 – 有专门的对象解码部分。 您可以使用它来将JSON对象解码为特定的Pythontypes。

这是一个例子:

 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) >>>> <class '__restricted__.User'> 

更新

如果您想通过json模块访问字典中的数据,请执行以下操作:

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

就像一个普通的字典。

这不是代码高尔夫,但这里是我最短的把戏,使用types.SimpleNamespace作为JSON对象的容器。

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

  • 可能更快/更小,因为它不会为每个对象创build一个类
  • 没有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) 

你可以试试这个:

 class User(object): def __init__(self, name, username, *args, **kwargs): self.name = name self.username = username import json j = json.loads(your_json) u = User(**j) 

只需创build一个新的对象,并将参数作为地图传递。

这是一个快速和肮脏的JSON泡菜替代品

 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() 

对于复杂的对象,可以使用JSON Pickle

用于将任意任意对象图序列化为JSON的Python库。 它几乎可以带任何Python对象,并把对象转换成JSON。 另外,它可以将对象重新组装成Python。

我写了一个名为any2any的小型(de)序列化框架,可以帮助在两种Pythontypes之间进行复杂的转换。

在你的情况下,我想你想从一个字典(用json.loads获得)转换为一个复杂的对象response.education ; response.name response.education ; response.name ,嵌套的结构response.education.id等等…所以这正是这个框架的。 该文档还不是很好,但通过使用any2any.simple.MappingToObject ,你应该能够很容易地做到这一点。 请问你是否需要帮助。

稍微修改@DS响应,从文件加载:

 def _json_object_hook(d): return namedtuple('X', d.keys())(*d.values()) def load_data(file_name): with open(file_name, 'r') as file_data: return file_data.read().replace('\n', '') def json2obj(file_name): return json.loads(load_data(file_name), object_hook=_json_object_hook) 

有一件事:这不能加载数字前面的项目。 喜欢这个:

 { "1_first_item": { "A": "1", "B": "2" } } 

因为“1_first_item”不是有效的python字段名称。

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