简单介绍Python中的JSON使用


Posted in Python onApril 28, 2015

JSON进阶

Python的dict对象可以直接序列化为JSON的{},不过,很多时候,我们更喜欢用class表示对象,比如定义Student类,然后序列化:

import json

class Student(object):
  def __init__(self, name, age, score):
    self.name = name
    self.age = age
    self.score = score

s = Student('Bob', 20, 88)
print(json.dumps(s))

运行代码,毫不留情地得到一个TypeError:

Traceback (most recent call last):
 ...
TypeError: <__main__.Student object at 0x10aabef50> is not JSON serializable

错误的原因是Student对象不是一个可序列化为JSON的对象。

如果连class的实例对象都无法序列化为JSON,这肯定不合理!

别急,我们仔细看看dumps()方法的参数列表,可以发现,除了第一个必须的obj参数外,dumps()方法还提供了一大堆的可选参数:

https://docs.python.org/2/library/json.html#json.dumps

这些可选参数就是让我们来定制JSON序列化。前面的代码之所以无法把Student类实例序列化为JSON,是因为默认情况下,dumps()方法不知道如何将Student实例变为一个JSON的{}对象。

可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可:

def student2dict(std):
  return {
    'name': std.name,
    'age': std.age,
    'score': std.score
  }

print(json.dumps(s, default=student2dict))

这样,Student实例首先被student2dict()函数转换成dict,然后再被顺利序列化为JSON。

不过,下次如果遇到一个Teacher类的实例,照样无法序列化为JSON。我们可以偷个懒,把任意class的实例变为dict:

print(json.dumps(s, default=lambda obj: obj.__dict__))

因为通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量。也有少数例外,比如定义了__slots__的class。

同样的道理,如果我们要把JSON反序列化为一个Student对象实例,loads()方法首先转换出一个dict对象,然后,我们传入的object_hook函数负责把dict转换为Student实例:

def dict2student(d):
  return Student(d['name'], d['age'], d['score'])

json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str, object_hook=dict2student))

运行结果如下:

<__main__.Student object at 0x10cd3c190>

打印出的是反序列化的Student实例对象。
小结

Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合Web标准,就可以使用json模块。

json模块的dumps()和loads()函数是定义得非常好的接口的典范。当我们使用时,只需要传入一个必须的参数。但是,当默认的序列化或反序列机制不满足我们的要求时,我们又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又做到了充分的扩展性和灵活性。

Python 相关文章推荐
Python中使用logging模块打印log日志详解
Apr 05 Python
基于python批量处理dat文件及科学计算方法详解
May 08 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
Jun 01 Python
Python函数的参数常见分类与用法实例详解
Mar 30 Python
python定时检测无响应进程并重启的实例代码
Apr 22 Python
python3获取当前目录的实现方法
Jul 29 Python
对Pytorch中nn.ModuleList 和 nn.Sequential详解
Aug 18 Python
python文字转语音的实例代码分析
Nov 12 Python
在OpenCV里实现条码区域识别的方法示例
Dec 04 Python
Django的CVB实例详解
Feb 10 Python
爬虫代理的cookie如何生成运行
Sep 22 Python
python模板入门教程之flask Jinja
Apr 11 Python
浅析Python中的序列化存储的方法
Apr 28 #Python
详解在Python和IPython中使用Docker
Apr 28 #Python
在Python程序中进行文件读取和写入操作的教程
Apr 28 #Python
介绍Python中的文档测试模块
Apr 28 #Python
Django中几种重定向方法
Apr 28 #Python
详解Python的单元测试
Apr 28 #Python
Python xlrd读取excel日期类型的2种方法
Apr 28 #Python
You might like
Destoon旺旺无法正常显示,点击提示“会员名不存在”的解决办法
2014/06/21 PHP
php查找指定目录下指定大小文件的方法
2014/11/28 PHP
PHP Try-catch 语句使用技巧
2016/02/28 PHP
浅析PHP中的i++与++i的区别及效率
2016/06/15 PHP
Web开发必知Javascript技巧大全
2016/02/23 Javascript
Vue数据驱动模拟实现3
2017/01/11 Javascript
Vue filters过滤器的使用方法
2017/07/14 Javascript
react-native DatePicker日期选择组件的实现代码
2017/09/12 Javascript
js实现关闭网页出现是否离开提示
2017/12/07 Javascript
用vue2.0实现点击选中active其他选项互斥的效果
2018/04/12 Javascript
微信小程序实现图片滚动效果示例
2018/12/05 Javascript
详解vue引入子组件方法
2019/02/12 Javascript
Vue CLI3基础学习之pages构建多页应用
2019/06/02 Javascript
vue中实现动态生成二维码的方法
2020/02/21 Javascript
js实现消灭星星(web简易版)
2020/03/24 Javascript
jQuery 选择方法及$(this)用法实例分析
2020/05/19 jQuery
[05:39]2014DOTA2西雅图国际邀请赛 淘汰赛7月14日TOPPLAY
2014/07/14 DOTA
[01:10]DOTA2次级职业联赛 - U5战队宣传片
2014/12/01 DOTA
[33:39]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第二局
2016/02/27 DOTA
使用Django和Python创建Json response的方法
2018/03/26 Python
python ChainMap 合并字典的实现步骤
2019/06/11 Python
Linux下远程连接Jupyter+pyspark部署教程
2019/06/21 Python
Python使用python-docx读写word文档
2019/08/26 Python
解决Django no such table: django_session的问题
2020/04/07 Python
css3针对移动端卡顿问题的解决(动画性能优化)
2020/02/14 HTML / CSS
特罗佩亚包官方网站:Tropea
2017/01/03 全球购物
英国家庭、花园、汽车和移动解决方案:Easylife Group
2018/05/23 全球购物
Omio葡萄牙:全欧洲低价大巴、火车和航班搜索和比价
2019/02/09 全球购物
德国大型箱包和皮具商店:Koffer
2019/10/01 全球购物
工程专业应届生求职信
2014/02/19 职场文书
哈弗商学院毕业生求职信
2014/02/26 职场文书
教育技术职业规划范文
2014/03/04 职场文书
幼儿园健康教育方案
2014/06/14 职场文书
长江三峡导游词
2015/01/31 职场文书
幼儿园五一劳动节活动总结
2015/02/09 职场文书
Python极值整数的边界探讨分析
2021/09/15 Python