在Python 中将类对象序列化为JSON


Posted in Python onApril 06, 2022

1. 引言

序列化是将对象转换为可以在以后保存和检索介质中的过程。比如,将对象的当前状态保存到文件中。对于一些复杂的项目,序列化是所有开发人员迟早要做的事情。
Python 语言的优点之一是它在许多常见的编程任务中易于使用,往往只需几行代码,就可以实现读取文件 IO、绘制图表等功能,序列化在 Python 中实现起来也非常容易。
在本文中,我将给大家带来将类对象序列化为 JSON 对象的一些技巧。

2. 举个栗子

为了讲述序列化的技巧,我们首先来定义一个类作为示例,

代码如下:

class LabelSimple:
def __init__(self, label, x, y, width, height):
self.label = label
self.x = x
self.y = y
self.width = width
self.height = height

如果我们想要将其序列化(比如直接打印类的对象),我们将会得到如下错误信息:

label = LabelSimple("person", 10, 10, 4, 10)
print(label)
>> __main__.LabelSimple object at 0x000002C3913EB2E0>

Python中的JSON 库提供了一个方便的方法,称为​ json.dumps()​ 。它可以将任何 Python 对象转换为 JSON。这听起来很简单,我们不妨来直接调用试试看。

import json

print(json.dumps(label))
>>...
/usr/lib/python3.7/json/encoder.py in default(self, o)
177
178 """
--> 179 raise TypeError(f'Object of type {o.__class__.__name__} '
180 f'is not JSON serializable')
181

TypeError: Object of type LabelSimple is not JSON serializable

​json.dumps()​ 为我们自定义对象调用相应的编码器,并且由于我们没有实现编码器而引发类对象错误。

3. 解决方案

3.1 使用 json.dumps() 和 __dict__

为了将上述类对象可以直接序列化后输出,我们能想到的最简单的方式就是使用内置的 __dict__ 方法来显示对象的内容.

代码如下:

label = Label("person", 10, 10, 4, 10)
print(label.__dict__)
print(json.dumps(label.__dict__))

输出如下:

{"label": "person", "x": 10, "y": 10, "width": 4, "height": 10}
{"label": "person", "x": 10, "y": 10, "width": 4, "height": 10}

可以看出使用上述方法后, ​print() 函数和 ​json.dumps() ​函数可以将类对象内容以JSON格式进行输出。

3.2 实现 __str__ 和 __repr__

上述实现虽然可以实现序列化的目的,但是我们每次都需要调用 __dict__方法,多少有点麻烦。我们还可以有更简单的方法,那就是实现类的内置函数__str__repr__

代码如下:

class Label:
def __init__(self, label, x, y, width, height):
self.label = label
self.x = x
self.y = y
self.width = width
self.height = height

def __iter__(self):
yield from {
"label": self.label,
"x": self.x,
"y": self.y,
"width": self.width,
"height": self.height
}.items()

def __str__(self):
return json.dumps(dict(self), ensure_ascii=False)

def __repr__(self):
return self.__str__()

调用代码如下:

label = Label("person", 10, 10, 4, 10)
print(label)
# print(json.dumps(label))

上述代码,print可以输出序列化后的JSON内容,但是json.dumps依旧不能正常工作,这是因为我们并没有实现encoder。

3.3 实现 JSON encoder

为了支持 json.dumps 用例,常用的方法是通过继承 JSONEncoder 来实现自定义编码器类。在上述例子中,由于我们希望对象是 JSON 字典格式,所以我们只是返回字典。

代码如下:

from json import JSONEncoder

class MyEncoder(JSONEncoder):
def default(self, obj):
return obj.__dict__

label = Label("person", 10, 10, 4, 10)
print(MyEncoder().encode(label))
print(json.dumps(label, cls=MyEncoder))
print(label)

输出如下:

# outputs of a Label class object
{"label": "person", "x": 10, "y": 10, "width": 4, "height": 10}
{"label": "person", "x": 10, "y": 10, "width": 4, "height": 10}
{"label": "person", "x": 10, "y": 10, "width": 4, "height": 10}

4. 总结

本文重点介绍了在Python中,如何来将自定义对象序列化为JSON以JOSN格式进行输出,由浅入深给出了不同的解决方案,并给出了相应的源代码。

到此这篇关于在Python 中将类对象序列化为JSON的文章就介绍到这了,更多相关Python 将类对象序列化JSON内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python实现多线程采集的2个代码例子
Jul 07 Python
对于Python异常处理慎用“except:pass”建议
Apr 02 Python
利用Python自带PIL库扩展图片大小给图片加文字描述的方法示例
Aug 08 Python
Python中对数组集进行按行打乱shuffle的方法
Nov 08 Python
详解小白之KMP算法及python实现
Apr 04 Python
Python中生成一个指定长度的随机字符串实现示例
Nov 06 Python
Pyqt5自适应布局实例
Dec 13 Python
python实现堆排序的实例讲解
Feb 21 Python
python如何调用字典的key
May 25 Python
python实现时间序列自相关图(acf)、偏自相关图(pacf)教程
Jun 03 Python
Pycharm在指定目录下生成文件和删除文件的实现
Dec 28 Python
OpenCV-Python实现人脸美白算法的实例
Jun 11 Python
Python中itertools库的四个函数介绍
Apr 06 #Python
如何用六步教会你使用python爬虫爬取数据
基于Python实现射击小游戏的制作
python使用opencv对图像添加噪声(高斯/椒盐/泊松/斑点)
python DataFrame中stack()方法、unstack()方法和pivot()方法浅析
浅谈Python中对象是如何被调用的
Apr 06 #Python
Python实现猜拳与猜数字游戏的方法详解
You might like
php中经典方法实现判断多维数组是否为空
2011/10/23 PHP
php 伪静态之IIS篇
2014/06/02 PHP
从零开始学习jQuery (二) 万能的选择器
2010/10/01 Javascript
JavaScript数组对象实现增加一个返回随机元素的方法
2015/07/27 Javascript
利用Vue.js指令实现全选功能
2016/09/08 Javascript
BootStrap按钮标签及基本样式
2016/11/23 Javascript
jQuery实现 RadioButton做必选校验功能
2017/06/15 jQuery
JS实现加载时锁定HTML页面元素的方法
2017/06/24 Javascript
jQuery查找和过滤_动力节点节点Java学院整理
2017/07/04 jQuery
js基于FileSaver.js 浏览器导出Excel文件的示例
2017/08/15 Javascript
Angular实现的简单定时器功能示例
2017/12/28 Javascript
安装vue-cli的简易过程
2018/05/22 Javascript
vuejs 动态添加input框的实例讲解
2018/08/24 Javascript
Nodejs调用Dll模块的方法
2018/09/17 NodeJs
一个小时快速搭建微信小程序的方法步骤
2019/04/15 Javascript
node实现爬虫的几种简易方式
2019/08/22 Javascript
vue中监听路由参数的变化及方法
2019/12/06 Javascript
仿照Element-ui实现一个简易的$message方法
2020/09/14 Javascript
[02:19]2014DOTA2国际邀请赛 专访820少年们一起去追梦吧
2014/07/14 DOTA
python使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
2015/05/15 Python
Python安装使用命令行交互模块pexpect的基础教程
2016/05/12 Python
python生成式的send()方法(详解)
2017/05/08 Python
Python 实现引用其他.py文件中的类和类的方法
2018/04/29 Python
Python socket套接字实现C/S模式远程命令执行功能案例
2018/07/06 Python
python实现屏保计时器的示例代码
2018/08/08 Python
解决pyttsx3无法封装的问题
2018/12/24 Python
使用CSS3编写类似iOS中的复选框及带开关的按钮
2016/04/11 HTML / CSS
HTML5 文件上传下载的实例代码
2017/07/03 HTML / CSS
丝芙兰加拿大官方网站:SEPHORA加拿大
2018/11/20 全球购物
施工人员岗位职责
2013/12/12 职场文书
工厂搬迁方案
2014/05/11 职场文书
文化产业实施方案
2014/06/07 职场文书
企业安全生产月活动总结
2014/07/05 职场文书
学校运动会报道稿
2014/09/23 职场文书
期末考试复习计划
2015/01/19 职场文书
幼儿园园长个人总结
2015/03/02 职场文书