简单介绍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 相关文章推荐
wxpython 学习笔记 第一天
Mar 16 Python
python不带重复的全排列代码
Aug 13 Python
python连接MySQL数据库实例分析
May 12 Python
Python绘制KS曲线的实现方法
Aug 13 Python
解决Pycharm界面的子窗口不见了的问题
Jan 17 Python
python执行精确的小数计算方法
Jan 21 Python
opencv实现静态手势识别 opencv实现剪刀石头布游戏
Jan 22 Python
python微信聊天机器人改进版(定时或触发抓取天气预报、励志语录等,向好友推送)
Apr 25 Python
Python中变量的输入输出实例代码详解
Jul 28 Python
Python中调用其他程序的方式详解
Aug 06 Python
python虚拟环境完美部署教程
Aug 06 Python
matplotlib对象拾取事件处理的实现
Jan 14 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
PHP将XML转数组过程详解
2013/11/13 PHP
Div Select挡住的解决办法
2008/08/07 Javascript
jQuery下通过$.browser来判断浏览器.
2011/04/05 Javascript
js一般方法改写成面向对象方法的无限级折叠菜单示例代码
2013/07/04 Javascript
get(0).tagName获得作用标签示例代码
2014/10/08 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
2015/02/04 Javascript
JavaScript操作Cookie详解
2015/02/28 Javascript
禁止按回车键提交表单的方法
2015/06/11 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
2015/12/25 Javascript
JS之获取样式的简单实现方法(推荐)
2016/09/13 Javascript
深入理解选择框脚本[推荐]
2016/12/13 Javascript
Node.js Mongodb 密码特殊字符 @的解决方法
2017/04/11 Javascript
Angular.js 4.x中表单Template-Driven Forms详解
2017/04/25 Javascript
vue-cli3全面配置详解
2018/11/14 Javascript
微信小程序实现图片滚动效果示例
2018/12/05 Javascript
vue中使用vue-cli接入融云实现即时通信
2019/04/19 Javascript
[47:06]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第一局
2016/03/05 DOTA
Python作用域用法实例详解
2016/03/15 Python
Django框架组成结构、基本概念与文件功能分析
2019/07/30 Python
Pycharm远程调试原理及具体配置详解
2019/08/08 Python
python通过nmap扫描在线设备并尝试AAA登录(实例代码)
2019/12/30 Python
使用Python脚本从文件读取数据代码实例
2020/01/19 Python
python3中celery异步框架简单使用+守护进程方式启动
2021/01/20 Python
你正在寻找的CSS3 动画技术
2011/07/27 HTML / CSS
Oroton中国官网:澳洲知名奢侈配饰品牌
2017/03/26 全球购物
无畏的旅行:Intrepid Travel
2017/12/20 全球购物
英国曼彻斯特宠物用品品牌:Bunty Pet Products
2019/07/27 全球购物
毕业生个人求职的自我评价
2013/10/28 职场文书
《可爱的动物》教学反思
2014/02/22 职场文书
通用自荐信范文
2014/03/14 职场文书
竞选部长演讲稿
2014/04/26 职场文书
环保倡议书300字
2014/05/15 职场文书
我的法兰西岁月观后感
2015/06/09 职场文书
2019年公司卫生管理制度样本
2019/08/21 职场文书
vue中data改变后让视图同步更新的方法
2021/03/29 Vue.js
JS实现页面炫酷的时钟特效示例
2022/08/14 Javascript