简单介绍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调用cmd复制文件代码分享
Dec 27 Python
python获取目录下所有文件的方法
Jun 01 Python
python实现爬虫统计学校BBS男女比例之多线程爬虫(二)
Dec 31 Python
python中OrderedDict的使用方法详解
May 05 Python
python 函数传参之传值还是传引用的分析
Sep 07 Python
python tensorflow学习之识别单张图片的实现的示例
Feb 09 Python
使用python进行拆分大文件的方法
Dec 10 Python
使用pyinstaller逆向.pyc文件
Dec 20 Python
python 串口读取+存储+输出处理实例
Dec 26 Python
Python多重继承之菱形继承的实例详解
Feb 12 Python
Python更换pip源方法过程解析
May 19 Python
在keras里实现自定义上采样层
Jun 28 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实现)只使用++运算实现加法,减法,乘法,除法
2013/06/27 PHP
php+ajax+json 详解及实例代码
2016/12/12 PHP
jquery 实现窗口的最大化不论什么情况
2013/09/03 Javascript
基于jquery的9行js轻松实现tab控件示例
2013/10/12 Javascript
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
jQuery中bind,live,delegate与one方法的用法及区别解析
2013/12/30 Javascript
使用focus方法让光标默认停留在INPUT框
2014/07/29 Javascript
PhantomJS快速入门教程(服务器端的 JavaScript API 的 WebKit)
2015/08/06 Javascript
以JavaScript来实现WordPress中的二级导航菜单的方法
2015/12/14 Javascript
Javascript数组Array方法解读
2016/03/13 Javascript
Bootstrap每天必学之模态框(Modal)插件
2016/04/26 Javascript
js实现获取两个日期之间所有日期的方法
2016/06/17 Javascript
那些精彩的JavaScript代码片段
2017/01/12 Javascript
JS开发中百度地图+城市联动实现实时触发查询地址功能
2017/04/13 Javascript
vue 循环加载数据并获取第一条记录的方法
2018/09/26 Javascript
vue 中基于html5 drag drap的拖放效果案例分析
2018/11/01 Javascript
JavaScript&quot;模拟事件&quot;的注意要点详解
2019/02/13 Javascript
微信小程序上传多图到服务器并获取返回的路径
2019/05/05 Javascript
Node.js操作MongoDB数据库实例分析
2020/01/19 Javascript
Python3数字求和的实例
2019/02/19 Python
Python 函数绘图及函数图像微分与积分
2019/11/20 Python
python代码如何实现余弦相似性计算
2020/02/09 Python
python爬虫开发之Request模块从安装到详细使用方法与实例全解
2020/03/09 Python
使用python处理题库表格并转化为word形式的实现
2020/04/14 Python
Python判断字符串是否为空和null方法实例
2020/04/26 Python
解决更改AUTH_USER_MODEL后出现的问题
2020/05/14 Python
django的autoreload机制实现
2020/06/03 Python
pytorch 多分类问题,计算百分比操作
2020/07/09 Python
CSS3 重置iphone浏览器按钮input,select等表单元素的默认样式
2014/10/11 HTML / CSS
Mountain Hardwear官网:攀岩服装和户外装备
2019/09/26 全球购物
马来西亚在线购物:POPLOOK.com
2019/12/09 全球购物
结构和类有什么异同
2012/07/16 面试题
基层干部2014全国两会学习心得体会
2014/03/10 职场文书
国庆节促销广告语2014
2014/09/19 职场文书
孝老爱亲事迹材料
2014/12/24 职场文书
员工工作失职检讨书范文!
2019/07/03 职场文书