简单介绍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脚本实现DNSPod DNS动态解析域名
Feb 14 Python
Python的Flask框架中集成CKeditor富文本编辑器的教程
Jun 13 Python
Python自动化开发学习之三级菜单制作
Jul 14 Python
pandas获取groupby分组里最大值所在的行方法
Apr 20 Python
Pycharm更换python解释器的方法
Oct 29 Python
linux安装python修改默认python版本方法
Mar 31 Python
Python数据类型之Number数字操作实例详解
May 08 Python
Python2.7:使用Pyhook模块监听鼠标键盘事件-获取坐标实例
Mar 14 Python
python用tkinter实现一个gui的翻译工具
Oct 26 Python
python3实现简单飞机大战
Nov 29 Python
python上下文管理的使用场景实例讲解
Mar 03 Python
opencv检测动态物体的实现
Jul 21 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
把77A收信机改造成收音机
2021/03/02 无线电
php中Smarty模板初体验
2011/08/08 PHP
Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
2013/06/14 PHP
详解PHP中的 input属性(隐藏 只读 限制)
2017/08/14 PHP
phpStorm+XDebug+chrome 配置详解
2019/04/01 PHP
RR vs IO BO3 第二场2.13
2021/03/10 DOTA
JavaScript起点(严格模式深度了解)
2013/01/28 Javascript
ANGULARJS中用NG-BIND指令实现单向绑定的例子
2014/12/08 Javascript
jquery实现ajax提交表单信息的简单方法(推荐)
2016/08/24 Javascript
详谈jQuery.load()和Jsp的include的区别
2017/04/12 jQuery
vue.js做一个简单的编辑菜谱功能
2018/05/08 Javascript
JavaScript面试技巧之数组的一些不low操作
2019/03/22 Javascript
详解在Javascript中进行面向切面编程
2019/04/28 Javascript
Vue SSR 即时编译技术的实现
2020/05/06 Javascript
解决vue addRoutes不生效问题
2020/08/04 Javascript
Python的Flask框架中实现登录用户的个人资料和头像的教程
2015/04/20 Python
Python生成随机数组的方法小结
2017/04/15 Python
Python探索之实现一个简单的HTTP服务器
2017/10/28 Python
matplotlib中legend位置调整解析
2017/12/19 Python
理解python中生成器用法
2017/12/20 Python
Python实现的随机森林算法与简单总结
2018/01/30 Python
TensorFlow实现Softmax回归模型
2018/03/09 Python
Tensorflow设置显存自适应,显存比例的操作
2020/02/03 Python
Keras Convolution1D与Convolution2D区别说明
2020/05/22 Python
Opencv图像处理:如何判断图片里某个颜色值占的比例
2020/06/03 Python
HTML5 在canvas中绘制文本附效果图
2014/06/23 HTML / CSS
美国市场上最实惠的送餐服务:Dinnerly
2018/03/18 全球购物
BASIC HOUSE官方旗舰店:韩国著名的服装品牌
2018/09/27 全球购物
考博专家推荐信模板
2013/12/02 职场文书
生产班组长岗位职责
2014/01/05 职场文书
人力资源主管岗位职责
2014/01/29 职场文书
机械设计制造及其自动化专业求职信
2014/06/17 职场文书
不服从公司安排检讨书
2014/09/24 职场文书
乡领导班子四风问题对照检查材料
2014/09/25 职场文书
写给女朋友的保证书
2015/05/09 职场文书
2016全国“质量月”活动标语口号
2015/12/26 职场文书