简单介绍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与Redis的连接教程
Apr 22 Python
Python建立Map写Excel表实例解析
Jan 17 Python
Python读取txt文件数据的方法(用于接口自动化参数化数据)
Jun 27 Python
python 自动重连wifi windows的方法
Dec 18 Python
python中使用 xlwt 操作excel的常见方法与问题
Jan 13 Python
python+selenium 定位到元素,无法点击的解决方法
Jan 30 Python
Python实现RGB与HSI颜色空间的互换方式
Nov 27 Python
Python文本处理简单易懂方法解析
Dec 19 Python
python 统计文件中的字符串数目示例
Dec 24 Python
安装Anaconda3及使用Jupyter的方法
Oct 27 Python
python 批量下载bilibili视频的gui程序
Nov 20 Python
python自动化发送邮件实例讲解
Jan 04 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
ThinkPHP CURD方法之order方法详解
2014/06/18 PHP
php表单提交与$_POST实例分析
2015/01/26 PHP
PHP使用缓存即时输出内容(output buffering)的方法
2015/08/03 PHP
调用WordPress函数统计文章访问量及PHP原生计数器的实现
2016/03/21 PHP
PHP实现的简单适配器模式示例
2017/06/22 PHP
ThinkPHP5&amp;5.1实现验证码的生成、使用及点击刷新功能示例
2020/02/07 PHP
php操作redis常见方法示例【key与value操作】
2020/04/14 PHP
js 创建快捷方式的代码(fso)
2010/11/19 Javascript
善用事件代理,警惕闭包的性能陷阱。
2011/01/20 Javascript
JQuery扩展插件Validate 3通过参数设置错误信息
2011/09/05 Javascript
如何在MVC应用程序中使用Jquery
2014/11/17 Javascript
浅谈JavaScript中Date(日期对象),Math对象
2015/02/05 Javascript
jQuery使用empty()方法删除元素及其所有子元素的方法
2015/03/26 Javascript
14款经典网页图片和文字特效的jQuery插件-前端开发必备
2015/08/25 Javascript
JQuery菜单效果的两个实例讲解(3)
2015/09/17 Javascript
Javascript获取图片原始宽度和高度的方法详解
2016/09/20 Javascript
JavaScript中全选、全不选、反选、无刷新删除、批量删除、即点即改入库(在yii框架中操作)的代码分享
2016/11/01 Javascript
原生js实现淘宝购物车功能
2020/06/23 Javascript
js制作可以延时消失的菜单
2017/01/13 Javascript
JS中传递参数的几种不同方法比较
2017/01/20 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
VUE.js实现动态设置输入框disabled属性
2019/10/28 Javascript
Angular8 实现table表格表头固定效果
2020/01/03 Javascript
vue子组件改变父组件传递的prop值通过sync实现数据双向绑定(DEMO)
2020/02/01 Javascript
Python绑定方法与非绑定方法详解
2017/08/18 Python
如何在django中添加日志功能
2020/02/06 Python
CSS3实现可关闭的下拉手风琴菜单效果
2015/08/31 HTML / CSS
美国知名的百货清仓店:Neiman Marcus Last Call
2016/08/03 全球购物
大学生护理专业自荐信
2013/10/03 职场文书
函授本科自我鉴定
2013/11/03 职场文书
精神文明建设标语
2014/06/16 职场文书
房屋授权无偿使用证明
2014/11/29 职场文书
武夷山导游词
2015/02/03 职场文书
2015年项目工作总结
2015/04/29 职场文书
python获取带有返回值的多线程
2022/05/02 Python
mysql序号rownum行号实现方式
2022/12/24 MySQL