简单介绍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 相关文章推荐
tensorflow 使用flags定义命令行参数的方法
Apr 23 Python
解决python3 urllib 链接中有中文的问题
Jul 16 Python
Django学习笔记之为Model添加Action
Apr 30 Python
python调试神器PySnooper的使用
Jul 03 Python
python视频按帧截取图片工具
Jul 23 Python
Python argparse模块应用实例解析
Nov 15 Python
python实现画循环圆
Nov 23 Python
python requests模拟登陆github的实现方法
Dec 26 Python
pytorch构建多模型实例
Jan 15 Python
windows10 pycharm下安装pyltp库和加载模型实现语义角色标注的示例代码
May 07 Python
基于Python的Jenkins的二次开发操作
May 12 Python
python在linux环境下安装skimage的示例代码
Oct 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中simplexml_load_string函数使用说明
2011/01/01 PHP
Yii使用DeleteAll连表删除出现报错问题的解决方法
2016/07/14 PHP
基于yaf框架和uploadify插件,做的一个导入excel文件,查看并保存数据的功能
2017/01/24 PHP
PHP实现模拟http请求的方法分析
2017/12/20 PHP
PHP使用函数用法详解
2018/09/30 PHP
[原创]网络复制内容时常用的正则+editplus
2006/11/30 Javascript
网站导致浏览器崩溃的原因总结(多款浏览器) 推荐
2010/04/15 Javascript
为jQuery.Treeview添加右键菜单的实现代码
2010/10/22 Javascript
JS实现字体选色板实例代码
2013/11/20 Javascript
js 鼠标移动显示图片的简单实例
2013/12/25 Javascript
Jquery实现自定义tooltip示例代码
2014/02/12 Javascript
JS图片无缝、平滑滚动代码
2014/03/11 Javascript
js生成验证码并直接在前端判断
2015/05/15 Javascript
手机端js和html5刮刮卡效果
2020/09/29 Javascript
利用node.js实现自动生成前端项目组件的方法详解
2017/07/12 Javascript
angularJS开发注意事项
2018/05/26 Javascript
react-router4按需加载(踩坑填坑)
2019/01/06 Javascript
详解微信小程序「渲染层网络层错误」的解决方法
2021/01/06 Javascript
[01:43]深扒TI7聊天轮盘语音出处4
2017/05/11 DOTA
通过实例浅析Python对比C语言的编程思想差异
2015/08/30 Python
利用python解决mysql视图导入导出依赖的问题
2017/12/17 Python
Python3.6实现连接mysql或mariadb的方法分析
2018/05/18 Python
什么是python的自省
2020/06/21 Python
css3让div随鼠标移动而抖动起来
2014/02/10 HTML / CSS
html5录音功能实战示例
2019/03/25 HTML / CSS
Banana Republic欧盟:美国都市简约风格的代表品牌
2018/05/09 全球购物
Urban Outfitters德国官网:美国跨国生活方式零售公司
2018/05/21 全球购物
Hudson Jeans官网:高级精制牛仔裤
2018/11/28 全球购物
初二生物教学反思
2014/02/03 职场文书
高中军训感想800字
2014/02/23 职场文书
工作疏忽、懈怠的检讨书
2014/09/11 职场文书
2014年会计个人工作总结
2014/11/24 职场文书
巾帼文明岗汇报材料
2014/12/24 职场文书
Python可视化学习之seaborn绘制矩阵图详解
2022/02/24 Python
【海涛dota解说】DCG联赛第一周 LGD VS DH
2022/04/01 DOTA
MySQL查询日期时间
2022/05/15 MySQL