在Python 中将类对象序列化为JSON
作者:sgzqc 发布时间:2023-06-11 16:41:32
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格式进行输出,由浅入深给出了不同的解决方案,并给出了相应的源代码。
来源:https://blog.51cto.com/u_15506603/5102623
猜你喜欢
- 寻觅工具确定任务之后第一步就是找个趁手的库来干活。 Python Excel上列出了xlrd、xlwt、xlutils这几个包,但是它们都比
- 前言:之前的文章我们已经开启了爬虫程序的exe之旅,但是我们最终实现的程序存在一个非常大的问题,当进行网络请求的时候,程序卡死,直到数据请求
- 本节内容:1.前言2.相关概念3.Python中的默认编码4.Python2与Python3中对字符串的支持5.字符编码转换一、前言Pyth
- 用于逐行分析文本的代码示例fileIN = open(sys.argv[1], "r")line = fileIN.re
- 跟着趣味开发python一起实现的弹球小游戏游戏运行效果实现流程1.创建游戏画布(创建ball类)2.增加几个动作(让小球移动、让小球来回反
- 文 | 李晓飞来源:Python 技术「ID: pythonall」最近有了一个新任务,需要将赛事视频,拆分成两分钟以内的小段,用
- 代码如下:<% Rem xml缓存类 '----------------------------
- 代码如下:--获取当前时间 Select getdate() --获取当前年月日 YY代表年,MM代表月,DD代表日,hh代表时
- 描述super() 函数是用于调用父类(超类)的一个方法。super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问
- 方法一在 Pillow 中,resize() 方法会强制将图片缩放到指定的大小,可能会导致图片变形或失真;而 thumbnail() 方法则
- ASP木马防御: 代码如下:const adTypeBinary=1 dim jpg(1):jpg(0)=CB
- 快速入门In [1]: import time# 获取当前时间In [25]: time.strftime("%Y-%m-%d_%
- 一、 文件的操作1.1创建文件格式:f = open(‘文件', ‘w')或者f = open(‘文件', ‘r
- Python应用编程需要用到的针对不同数据库引擎的数据库接口:http://wiki.python.org/moin/DatabaseInt
- 对于大前端来说,JS可谓是我们的神器,从页面的效果到数据的传递,再到后台的业务,无处不充斥着JS的身影,但是万能的JS也有贪玩的时候,某一时
- 我写的这个程序import tensorflow as tfsess=tf.InteractiveSession()x=tf.Variabl
- 近日闲来无事,总有一种无形的力量萦绕在朕身边,让朕精神涣散,昏昏欲睡。可是,像朕这么有职业操守的社畜怎么能在上班期间睡瞌睡呢,我不禁陷入了沉
- 问题有二进制文件中保存了 20 亿个 2 Bytes 的数,需将其读出,每 20000 个数作图,拟合后输出结果。解决# -*- codin
- 原文地址:30 Days of Mootools 1.2 Tutorials - Day 21 - Classes part
- 通过视图来访问数据,其优点是非常明显的。如可以起到数据保密、保证数据的逻辑独立性、简化查询操作等等。但是,话说回来,SQL Server数据