简单介绍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 添加用户设置密码并发邮件给root用户
Jul 25 Python
详谈套接字中SO_REUSEPORT和SO_REUSEADDR的区别
Apr 28 Python
Python爬虫实现全国失信被执行人名单查询功能示例
May 03 Python
查看TensorFlow checkpoint文件中的变量名和对应值方法
Jun 14 Python
详解Django中间件的5种自定义方法
Jul 26 Python
详解Python安装tesserocr遇到的各种问题及解决办法
Mar 07 Python
Python秒算24点实现及原理详解
Jul 29 Python
用Python解数独的方法示例
Oct 24 Python
解决Python图形界面中设置尺寸的问题
Mar 05 Python
Python使用Pyqt5实现简易浏览器(最新版本测试过)
Apr 27 Python
PyQt5 QDockWidget控件应用详解
Aug 12 Python
python实现录音功能(可随时停止录音)
Oct 26 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
无线电广播的开始
2002/01/30 无线电
如何冲泡挂耳包咖啡?技巧是什么
2021/03/04 冲泡冲煮
检查用户名是否已在mysql中存在的php写法
2014/01/20 PHP
Laravel框架学习笔记(二)项目实战之模型(Models)
2014/10/15 PHP
PHP文件操作方法汇总
2015/07/01 PHP
PHP与Ajax相结合实现登录验证小Demo
2016/03/16 PHP
php将html转为图片的实现方法
2017/05/19 PHP
如何利用预加载优化Laravel Model查询详解
2017/08/11 PHP
SlideView 图片滑动(扩展/收缩)展示效果
2010/08/01 Javascript
javascript中将Object转换为String函数代码 (json str)
2012/04/29 Javascript
JS getAttribute和setAttribute(取得和设置属性)的使用介绍
2013/07/10 Javascript
js读取注册表的键值示例
2013/09/25 Javascript
javaScript如何生成xmlhttp
2013/12/16 Javascript
jQuery之Deferred对象详解
2014/09/04 Javascript
HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列
2015/04/26 Javascript
jquery插件NProgress.js制作网页加载进度条
2015/06/05 Javascript
nodejs实现bigpipe异步加载页面方案
2016/01/26 NodeJs
select获取下拉框的值 下拉框默认选中方法
2018/02/28 Javascript
微信小程序实现音频文件播放进度的实例代码
2020/03/02 Javascript
原生JS实现萤火虫效果
2020/03/07 Javascript
基于Vue sessionStorage实现保留搜索框搜索内容
2020/06/01 Javascript
vue element-ul实现展开和收起功能的实例代码
2020/11/25 Vue.js
Python排序搜索基本算法之冒泡排序实例分析
2017/12/09 Python
python实现单链表中删除倒数第K个节点的方法
2018/09/28 Python
在Python中字典按值排序的实现方法
2020/11/12 Python
CSS3制作漂亮的照片墙的实现代码
2016/06/08 HTML / CSS
简述Html5 IphoneX 适配方法
2018/02/08 HTML / CSS
瑞典时尚耳机品牌:Urbanears
2017/07/26 全球购物
PHP面试题大全
2015/10/16 面试题
承诺书怎么写
2014/03/26 职场文书
股权收购意向书
2014/04/01 职场文书
2015年电气技术员工作总结
2015/07/24 职场文书
MySQL 慢查询日志深入理解
2021/04/22 MySQL
python opencv通过按键采集图片源码
2021/05/20 Python
关于使用Redisson订阅数问题
2022/01/18 Redis
CSS浮动引起的高度塌陷问题
2022/08/05 HTML / CSS