在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实现猜数字游戏(无重复数字)示例分享
Mar 29 Python
python正常时间和unix时间戳相互转换的方法
Apr 23 Python
详解python的几种标准输出重定向方式
Aug 15 Python
Python排序搜索基本算法之堆排序实例详解
Dec 08 Python
用Python将mysql数据导出成json的方法
Aug 21 Python
python3 正则表达式基础廖雪峰
Mar 25 Python
如何安装并在pycharm使用selenium的方法
Apr 30 Python
Python实现动态循环输出文字功能
May 07 Python
解决python运行启动报错问题
Jun 01 Python
Python Socket TCP双端聊天功能实现过程详解
Jun 15 Python
python3中数组逆序输出方法
Dec 01 Python
如何用Python搭建gRPC服务
Jun 30 Python
Python中itertools库的四个函数介绍
Apr 06 #Python
如何用六步教会你使用python爬虫爬取数据
基于Python实现射击小游戏的制作
python使用opencv对图像添加噪声(高斯/椒盐/泊松/斑点)
python DataFrame中stack()方法、unstack()方法和pivot()方法浅析
浅谈Python中对象是如何被调用的
Apr 06 #Python
Python实现猜拳与猜数字游戏的方法详解
You might like
php 过滤器实现代码
2010/08/09 PHP
php操作mysqli(示例代码)
2013/10/28 PHP
用 Javascript 验证表单(form)中的单选(radio)值
2009/09/08 Javascript
加载jQuery后$冲突的解决办法
2010/07/09 Javascript
关于this和self的使用说明
2010/08/01 Javascript
jquery ajax实现下拉框三级无刷新联动,且保存保持选中值状态
2013/10/29 Javascript
利用js实现在浏览器状态栏显示访问者在本页停留的时间
2013/12/29 Javascript
zepto.js中tap事件阻止冒泡的实现方法
2015/02/12 Javascript
浅谈angularJS 作用域
2015/07/05 Javascript
JQ技术实现注册页面带有校验密码强度
2015/07/27 Javascript
JS根据浏览器窗口大小实时动态改变网页文字大小的方法
2016/02/25 Javascript
EasyUI布局 高度自适应
2016/06/04 Javascript
完美解决jQuery符号$与其他javascript 库、框架冲突的问题
2016/08/09 Javascript
微信小程序 loading(加载中提示框)实例
2016/10/28 Javascript
js, jQuery实现全选、反选功能
2017/03/08 Javascript
解决BootStrap Fileinput手机图片上传显示旋转问题
2017/06/01 Javascript
JavaScript选取(picking)和反选(rejecting)对象的属性方法
2017/08/16 Javascript
详解JavaScript中的强制类型转换
2019/04/15 Javascript
解决vue cli使用typescript后打包巨慢的问题
2019/09/30 Javascript
vue 动态添加class,三个以上的条件做判断方式
2020/11/02 Javascript
python使用opencv读取图片的实例
2017/08/17 Python
Python中的浮点数原理与运算分析
2017/10/12 Python
Python批量更改文件名的实现方法
2017/10/29 Python
pycharm使用matplotlib.pyplot不显示图形的解决方法
2018/10/28 Python
对python 调用类属性的方法详解
2019/07/02 Python
Python3.5 win10环境下导入kera/tensorflow报错的解决方法
2019/12/19 Python
python使用re模块爬取豆瓣Top250电影
2020/10/20 Python
详解Html5 Canvas画线有毛边解决方法
2018/03/01 HTML / CSS
HTML5实现可缩放时钟代码
2017/08/28 HTML / CSS
GNC健安喜官方海外旗舰店:美国著名保健品牌
2017/01/04 全球购物
美国女性运动零售品牌:Lady Foot Locker
2017/05/12 全球购物
Charlotte Tilbury澳大利亚官网:英国美妆品牌
2018/10/05 全球购物
运动会广播稿300字
2014/01/10 职场文书
中药学专业求职信
2014/05/31 职场文书
信息技术远程培训心得体会
2016/01/09 职场文书
60句有关成长的名言
2019/09/04 职场文书