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

Posted Python学习与数据挖掘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Python 中如何将类对象序列化为JSON?相关的知识,希望对你有一定的参考价值。

序列化是将对象转换为可以在以后保存和检索介质中的过程。比如,将对象的当前状态保存到文件中。对于一些复杂的项目,序列化是所有开发人员迟早要做的事情。

Python 语言的优点之一是它在许多常见的编程任务中易于使用,往往只需几行代码,就可以实现读取文件 IO、绘制图表等功能,序列化在 Python 中实现起来也非常容易。

在本文中,我将给大家带来将类对象序列化为 JSON 对象的一些技巧。

举个栗子

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

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() 为我们自定义对象调用相应的编码器,并且由于我们没有实现编码器而引发类对象错误。

简单方案

为了将上述类对象可以直接序列化后输出,我们能想到的最简单的方式就是使用内置的 __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格式进行输出。

进阶方案

上述实现虽然可以实现序列化的目的,但是我们每次都需要调用 __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。

实现 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

总结

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

推荐文章

技术交流

欢迎转载、收藏、有所收获点赞支持一下!

目前开通了技术交流群,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友

  • 方式①、发送如下图片至微信,长按识别,后台回复:加群;
  • 方式②、添加微信号:dkl88191,备注:来自CSDN
  • 方式③、微信搜索公众号:Python学习与数据挖掘,后台回复:加群

以上是关于在Python 中如何将类对象序列化为JSON?的主要内容,如果未能解决你的问题,请参考以下文章

将类序列化为 .json 文件

使用 WCF 将类序列化为 xsd.exe 生成的 JSON

如何将 django/python 中的模型对象列表序列化为 JSON

python Django Views - 如何将django对象数组序列化为平面JSON(排除模型,pk和fields节点)

使用 JsonConvert.DeserializeObject 或 JObject.Parse 将类反序列化为 c# 中的字典

将json字符串反序列化为python中的对象