简单介绍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 相关文章推荐
win7 下搭建sublime的python开发环境的配置方法
Jun 18 Python
Python标准库之多进程(multiprocessing包)介绍
Nov 25 Python
Python常见异常分类与处理方法
Jun 04 Python
Python实现一个Git日志统计分析的小工具
Dec 14 Python
Python http接口自动化测试框架实现方法示例
Dec 06 Python
使用python打印十行杨辉三角过程详解
Jul 10 Python
Python守护进程实现过程详解
Feb 10 Python
详解django使用include无法跳转的解决方法
Mar 19 Python
python实现简易版学生成绩管理系统
Jun 22 Python
Python如何配置环境变量详解
May 18 Python
Python快速优雅的批量修改Word文档样式
May 20 Python
如何使用PyCharm及常用配置详解
Jun 03 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
BBS(php &amp; mysql)完整版(六)
2006/10/09 PHP
php URL编码解码函数代码
2009/03/10 PHP
用PHP提取中英文词语以及数字的首字母的方法介绍
2013/04/23 PHP
php中fsockopen用法实例
2015/01/05 PHP
PHP中ltrim()函数的用法与实例讲解
2019/03/28 PHP
php+websocket 实现的聊天室功能详解
2020/05/27 PHP
JavaScript 在线压缩和格式化收藏
2009/01/16 Javascript
关于javascript 回调函数中变量作用域的讨论
2009/09/11 Javascript
详细讲解JS节点知识
2010/01/31 Javascript
JS模拟面向对象全解(一、类型及传递)
2011/07/13 Javascript
jquery引用方法时传递参数原理分析
2014/10/13 Javascript
javascript设置连续两次点击按钮时间间隔的方法
2014/10/28 Javascript
JS+CSS实现简易的滑动门效果代码
2015/09/24 Javascript
javascript事件冒泡简单示例
2016/06/20 Javascript
js滚轮事件兼容性问题需要注意哪些
2016/11/15 Javascript
babel基本使用详解
2017/02/17 Javascript
Vue 组件(component)教程之实现精美的日历方法示例
2018/01/08 Javascript
JavaScript实现正则去除a标签并保留内容的方法【测试可用】
2018/07/18 Javascript
KOA+egg.js集成kafka消息队列的示例
2018/11/09 Javascript
jquery插件开发模式实例详解
2019/07/20 jQuery
vue+element项目中过滤输入框特殊字符小结
2019/08/07 Javascript
详解JavaScript 作用域
2020/07/14 Javascript
利用js canvas实现五子棋游戏
2020/10/11 Javascript
[03:14]DOTA2斧王 英雄基础教程
2013/11/26 DOTA
python错误:AttributeError: 'module' object has no attribute 'setdefaultencoding'问题的解决方法
2014/08/22 Python
Django开发中的日志输出的方法
2018/07/02 Python
对python pandas读取剪贴板内容的方法详解
2019/01/24 Python
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
教育系毕业生中文求职信范文
2013/10/06 职场文书
出国留学担保书
2014/05/20 职场文书
幼儿园健康教育方案
2014/06/14 职场文书
2014年度个人总结范文
2015/03/09 职场文书
清明节主题班会
2015/08/14 职场文书
python 批量压缩图片的脚本
2021/06/02 Python
Spring依赖注入多种类型数据的示例代码
2022/03/31 Java/Android
分析MySQL优化 index merge 后引起的死锁
2022/04/19 MySQL