在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 相关文章推荐
Apache如何部署django项目
May 21 Python
Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容
Feb 23 Python
Python读取mat文件,并保存为pickle格式的方法
Oct 23 Python
Python版名片管理系统
Nov 30 Python
使用python来调用CAN通讯的DLL实现方法
Jul 03 Python
keras 特征图可视化实例(中间层)
Jan 24 Python
python实现微信打飞机游戏
Mar 24 Python
python初步实现word2vec操作
Jun 09 Python
解决keras加入lambda层时shape的问题
Jun 11 Python
matplotlib图例legend语法及设置的方法
Jul 28 Python
Matlab求解数组中的最大值及它所在的具体位置
Apr 16 Python
Python用any()函数检查字符串中的字母以及如何使用all()函数
Apr 14 Python
Python中itertools库的四个函数介绍
Apr 06 #Python
如何用六步教会你使用python爬虫爬取数据
基于Python实现射击小游戏的制作
python使用opencv对图像添加噪声(高斯/椒盐/泊松/斑点)
python DataFrame中stack()方法、unstack()方法和pivot()方法浅析
浅谈Python中对象是如何被调用的
Apr 06 #Python
Python实现猜拳与猜数字游戏的方法详解
You might like
PHP删除数组中特定元素的两种方法
2013/07/02 PHP
php中mail函数发送邮件失败的解决方法
2014/12/24 PHP
ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
2019/03/11 PHP
浅谈javascript 面向对象编程
2009/10/28 Javascript
自写简单JS判断是否已经弹出页面
2010/10/20 Javascript
jquery+css实现绚丽的横向二级下拉菜单-附源码下载
2015/08/23 Javascript
详解JavaScript的回调函数
2015/11/20 Javascript
JavaScript从0开始构思表情插件
2016/07/26 Javascript
AngularJS模仿Form表单提交的实现代码
2016/12/08 Javascript
微信小程序 详解Page中data数据操作和函数调用
2017/01/12 Javascript
bootstrap如何让dropdown menu按钮式下拉框长度一致
2017/04/10 Javascript
Vue.js使用$.ajax和vue-resource实现OAuth的注册、登录、注销和API调用
2017/05/10 Javascript
vue2.0 keep-alive最佳实践
2017/07/06 Javascript
JS实现验证码倒计时的注册页面
2018/01/02 Javascript
jQuery实现动态显示select下拉列表数据的方法
2018/02/05 jQuery
vue 根据数组中某一项的值进行排序的方法
2018/08/30 Javascript
webpack+express实现文件精确缓存的示例代码
2020/06/11 Javascript
解决vue-router 嵌套路由没反应的问题
2020/09/22 Javascript
Python中的rjust()方法使用详解
2015/05/19 Python
Python中Django框架下的staticfiles使用简介
2015/05/30 Python
Python中字符串格式化str.format的详细介绍
2017/02/17 Python
python使用selenium实现批量文件下载
2019/03/11 Python
UGG雪地靴荷兰官网:UGG荷兰
2016/09/09 全球购物
APM Monaco中国官网:来自摩纳哥珠宝品牌
2017/12/27 全球购物
工作室成员个人发展规划范文
2014/01/24 职场文书
会计助理岗位职责
2014/02/17 职场文书
新春寄语大全
2014/04/09 职场文书
《去年的树》教学反思
2014/04/11 职场文书
欢迎领导标语
2014/06/27 职场文书
2014年办公室文秘工作总结
2014/12/09 职场文书
小学班主任事迹材料
2014/12/17 职场文书
冲出亚马逊观后感
2015/06/03 职场文书
2016国培研修心得体会
2016/01/08 职场文书
职业规划从高考志愿专业选择开始
2019/08/08 职场文书
MySQL中rank() over、dense_rank() over、row_number() over用法介绍
2022/03/23 MySQL