简单介绍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 相关文章推荐
pip 错误unused-command-line-argument-hard-error-in-future解决办法
Jun 01 Python
Python Queue模块详解
Nov 30 Python
Python 基础教程之str和repr的详解
Aug 20 Python
Python实现mysql数据库更新表数据接口的功能
Nov 19 Python
python验证码识别教程之灰度处理、二值化、降噪与tesserocr识别
Jun 04 Python
Python用5行代码写一个自定义简单二维码
Oct 21 Python
Flask框架web开发之零基础入门
Dec 10 Python
python 实现查找文件并输出满足某一条件的数据项方法
Jun 12 Python
Django对models里的objects的使用详解
Aug 17 Python
使用python切片实现二维数组复制示例
Nov 26 Python
Keras多线程机制与flask多线程冲突的解决方案
May 28 Python
python中sqllite插入numpy数组到数据库的实现方法
Jun 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
php中json_encode中文编码问题分析
2011/09/13 PHP
浅谈php自定义错误日志
2015/02/13 PHP
ThinkPHP框架表单验证操作方法
2017/07/19 PHP
PHP基于pdo的数据库操作类【可支持mysql、sqlserver及oracle】
2018/05/21 PHP
PDO::errorInfo讲解
2019/01/28 PHP
不常用但很实用的PHP预定义变量分析
2019/06/25 PHP
JavaScript面向对象之静态与非静态类
2010/02/03 Javascript
php读取sqlite数据库入门实例代码
2014/06/25 Javascript
ECMAScript6中Set/WeakSet详解
2015/06/12 Javascript
Javascript中Array用法实例分析
2015/06/13 Javascript
针对初学者的jQuery入门指南
2015/08/15 Javascript
如何利用JS通过身份证号获取当事人的生日、年龄、性别
2016/01/22 Javascript
JavaScript实现iframe自动高度调整和不同主域名跨域
2016/02/27 Javascript
jQuery验证插件validate使用方法详解
2020/09/13 Javascript
vue2.0 循环遍历加载不同图片的方法
2018/03/06 Javascript
vue写一个组件
2018/04/09 Javascript
通过jquery获取上传文件名称、类型和大小的实现代码
2018/04/19 jQuery
解决Vue 给mapState中定义的属性赋值报错的问题
2020/06/22 Javascript
vue-amap根据地址回显地图并mark的操作
2020/11/03 Javascript
vue组件中节流函数的失效的原因和解决方法
2020/12/02 Vue.js
[02:09]抵达西雅图!中国军团加油!
2014/07/07 DOTA
[01:46]2020完美世界全国高校联赛秋季赛报名开启
2020/10/15 DOTA
Python如何筛选序列中的元素的方法实现
2019/07/15 Python
解决Pycharm 包已经下载,但是运行代码提示找不到模块的问题
2019/08/31 Python
Python参数传递对象的引用原理解析
2020/05/22 Python
Django返回HTML文件的实现方法
2020/09/17 Python
美国葡萄酒网上商店:Martha Stewart Wine Co.
2019/03/17 全球购物
极度干燥澳大利亚官方网站:Superdry澳大利亚
2019/03/28 全球购物
Linux如何修改文件和文件夹的权限
2012/06/27 面试题
黄金酒广告词
2014/03/21 职场文书
十佳护士先进事迹
2014/05/08 职场文书
敬老模范事迹
2014/05/21 职场文书
保洁公司服务承诺书
2014/05/28 职场文书
经济国贸专业求职信
2014/06/18 职场文书
个人事迹材料范文
2014/12/29 职场文书
2015年化验室工作总结
2015/04/23 职场文书