首頁 > 軟體

在Python 中將類物件序列化為JSON

2022-04-06 16:01:11

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內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com