简单介绍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如何实现远程控制电脑(结合微信)
Dec 21 Python
利用Python获取赶集网招聘信息前篇
Apr 18 Python
Python中线程的MQ消息队列实现以及消息队列的优点解析
Jun 29 Python
Python调用C语言的方法【基于ctypes模块】
Jan 22 Python
在python 不同时区之间的差值与转换方法
Jan 14 Python
PIL对上传到Django的图片进行处理并保存的实例
Aug 07 Python
python如何实现不可变字典inmutabledict
Jan 08 Python
python GUI库图形界面开发之PyQt5访问系统剪切板QClipboard类详细使用方法与实例
Feb 27 Python
解决Jupyter NoteBook输出的图表太小看不清问题
Apr 16 Python
django 模版关闭转义方式
May 14 Python
PyQT5 实现快捷键复制表格数据的方法示例
Jun 19 Python
详解Python中@staticmethod和@classmethod区别及使用示例代码
Dec 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
PHP4实际应用经验篇(1)
2006/10/09 PHP
php与c 实现按行读取文件实例代码
2017/01/03 PHP
TP3.2批量上传文件或图片 同名冲突问题的解决方法
2017/08/01 PHP
关于php支持的协议与封装协议总结(推荐)
2017/11/17 PHP
php项目中类的自动加载实例讲解
2019/09/12 PHP
javascript中的有名函数和无名函数
2007/10/17 Javascript
asp 取文本框名称代码
2008/12/02 Javascript
js控制鼠标事件移动及移出效果显示
2014/10/19 Javascript
分享jQuery插件的学习笔记
2016/01/14 Javascript
JavaScript学习笔记之创建对象
2016/03/25 Javascript
jQuery多文件异步上传带进度条实例代码
2016/08/16 Javascript
JS实现简单的选择题测评系统代码思路详解(demo)
2017/09/03 Javascript
解决vue-cli脚手架打包后vendor文件过大的问题
2018/09/27 Javascript
js html实现计算器功能
2018/11/13 Javascript
React事件处理的机制及原理
2018/12/03 Javascript
使用weixin-java-miniapp配置进行单个小程序的配置详解
2019/03/29 Javascript
详解jquery和vue对比
2019/04/16 jQuery
微信小程序防止多次点击跳转(函数节流)
2019/09/19 Javascript
JavaScript观察者模式原理与用法实例详解
2020/03/10 Javascript
vue项目中使用bpmn-自定义platter的示例代码
2020/05/11 Javascript
Python 列表list使用介绍
2014/11/30 Python
简单介绍Python的Django框架加载模版的方式
2015/07/20 Python
TensorFlow模型保存和提取的方法
2018/03/08 Python
Python Django框架单元测试之文件上传测试示例
2019/05/17 Python
Django处理Ajax发送的Get请求代码详解
2019/07/29 Python
python 画条形图(柱状图)实例
2020/04/24 Python
pytorch掉坑记录:model.eval的作用说明
2020/06/23 Python
python两种获取剪贴板内容的方法
2020/11/06 Python
前端隐藏出边界内容的实现方法
2016/04/14 HTML / CSS
C语言中break与continue的区别
2012/07/12 面试题
法院授权委托书范文
2014/08/02 职场文书
机械工程及其自动化专业求职信
2014/08/08 职场文书
学校政风行风评议工作总结
2014/10/21 职场文书
陪护人员误工证明
2015/06/24 职场文书
Tensorflow与RNN、双向LSTM等的踩坑记录及解决
2021/05/31 Python
详解Go语言Slice作为函数参数的使用
2021/07/02 Golang