简单介绍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将图片文件转换成base64编码的方法
Mar 14 Python
Python Sql数据库增删改查操作简单封装
Apr 18 Python
python中使用psutil查看内存占用的情况
Jun 11 Python
mac下pycharm设置python版本的图文教程
Jun 13 Python
selenium+python实现1688网站验证码图片的截取功能
Aug 14 Python
influx+grafana自定义python采集数据和一些坑的总结
Sep 17 Python
解决python selenium3启动不了firefox的问题
Oct 13 Python
python自定义函数实现最大值的输出方法
Jul 09 Python
python操作链表的示例代码
Sep 27 Python
Python实现微信表情包炸群功能
Jan 28 Python
手把手教你使用TensorFlow2实现RNN
Jul 15 Python
python基础之类方法和静态方法
Oct 24 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 反向排序和随机排序代码
2010/06/30 PHP
PHP mcrypt可逆加密算法分析
2011/07/19 PHP
JS中encodeURIComponent函数用php解码的代码
2012/03/01 PHP
php筛选不存在的图片资源
2015/04/28 PHP
PHP抽奖算法程序代码分享
2015/10/08 PHP
PHP判断是否是微信打开还是浏览器打开的方法
2019/02/27 PHP
javascript 获取图片颜色
2009/04/05 Javascript
JavaScript.Encode手动解码技巧
2010/07/14 Javascript
jquery键盘事件介绍
2011/01/31 Javascript
node.js中的fs.fchmodSync方法使用说明
2014/12/16 Javascript
如何防止JavaScript自动插入分号
2015/11/05 Javascript
JS中Eval解析JSON字符串的一个小问题
2016/02/21 Javascript
原生JS实现图片左右轮播
2016/12/30 Javascript
bootstrap vue.js实现tab效果
2017/02/07 Javascript
关于页面刷新vuex数据消失问题解决方案
2017/07/03 Javascript
详解webpack与SPA实践之开发环境搭建
2017/12/18 Javascript
Vue2.0使用嵌套路由实现页面内容切换/公用一级菜单控制页面内容切换(推荐)
2019/05/08 Javascript
JQuery复选框全选效果如何实现
2020/05/08 jQuery
ES6新增的数组知识实例小结
2020/05/23 Javascript
JS 逻辑判断不要只知道用 if-else 和 switch条件判断(小技巧)
2020/05/27 Javascript
[01:08:44]NB vs VP 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
在Python中使用HTML模版的教程
2015/04/29 Python
使用Python编写基于DHT协议的BT资源爬虫
2016/03/19 Python
Python正则替换字符串函数re.sub用法示例
2017/01/19 Python
Python并发concurrent.futures和asyncio实例
2020/05/04 Python
python脚本使用阿里云slb对恶意攻击进行封堵的实现
2021/02/04 Python
会计演讲稿范文
2014/05/23 职场文书
最美乡村医生事迹材料
2014/06/02 职场文书
酒店端午节活动方案
2014/08/26 职场文书
平面设计师岗位职责
2014/09/18 职场文书
合作协议书模板2014
2014/09/26 职场文书
2014年组织委员工作总结
2014/12/01 职场文书
研究生给导师的自荐信
2015/03/06 职场文书
详解MySQL 联合查询优化机制
2021/05/10 MySQL
Python List remove()实例用法详解
2021/08/02 Python
Win10多屏显示如何设置?Win10电脑多屏显示设置操作方法
2022/07/07 数码科技