Python - 序列化

你好啊,未來的 Python 大師們!今天,我們將深入探討序列化的迷人世界。如果這個詞聽起來讓人心生畏懼,別擔心——在上完這堂課之後,你將能像專家一樣序列化數據!讓我們一起踏上這段激動人心的旅程。

Python - Serialization

Python 中的序列化

想象一下你正在為旅行打包。你需要將所有的物品塞進一個行李箱。序列化數據做的就是這樣的事情——它將數據整齊地打包起來,以便於存儲或傳輸到其他地方。在 Python 的語境中,序列化就是將複雜的數據結構轉換成可以輕易存儲或傳輸的格式的過程。

你會問,這為什麼重要?嗯,假設你創建了一個出色的 Python 程式,可以生成你喜歡的電影列表。你想保存這個列表,以便稍後使用或傳給朋友。序列化讓你能够做到這一點!

Python 的序列化庫

Python 是一種非常慷慨的語言,為我們提供了多個序列化庫。這就像為不同的旅行提供不同類型的行李箱一樣。讓我們看看最常見的一些:

描述
Pickle Python 的內置序列化模塊
JSON JavaScript 對象表示法,非常適合網頁應用程式
YAML YAML 不是標記語言,人類可讀的格式

我們將詳細探討每一個,但先從最 Python 風格的一個開始:Pickle。

使用 Pickle 模塊進行序列化

Pickle 是 Python 用於序列化的首選模塊。它就像一把瑞士軍刀——多用途且內置於 Python。讓我們看看它是如何工作的:

import pickle

# 我們喜歡的電影列表
favorite_movies = ['The Matrix', 'Star Wars', 'The Lord of the Rings']

# 序列化列表
with open('movies.pkl', 'wb') as file:
pickle.dump(favorite_movies, file)

print("電影列表已經被序列化!")

在這個例子中,我們正在將我們喜歡的電影列表“醃漬”。dump() 函數在這裡完成了大部分工作,將我們的列表轉換為二進制格式並保存到名為 'movies.pkl' 的文件中。

現在,讓我們看看如何將我們的列表找回來:

# 反序列化列表
with open('movies.pkl', 'rb') as file:
loaded_movies = pickle.load(file)

print("反序列化後的電影列表:", loaded_movies)

瞧!我們成功地將我們的行李箱(或者說是這個例子中的醃漬罐)打開了。load() 函數讀取二進制文件,並將其轉換回 Python 對象。

Pickle 協議

Pickle 使用所謂的“協議”來決定如何序列化對象。將這些視為行李箱的不同打包方法。Python 3 支援 5 個協議(從 0 到 4),數字越大越高效,但也可能與舊版本的 Python 的兼容性較低。

import pickle

data = {'name': 'Alice', 'age': 30}

# 使用協議 4(Python 3 中最有效率的)
serialized = pickle.dumps(data, protocol=4)
print("序列化後的數據:", serialized)

# 反序列化
deserialized = pickle.loads(serialized)
print("反序列化後的數據:", deserialized)

在這個例子中,我們使用 dumps() 將數據序列化為字符串而不是文件,並指定協議 4 以達到最高效率。

Pickler 和 Unpickler 類

為了更精細地控制序列化過程,Python 提供了 Pickler 和 Unpickler 類。這些就像是你個人的打包助手:

import pickle

class PickleHelper:
def __init__(self, filename):
self.filename = filename

def save_data(self, data):
with open(self.filename, 'wb') as file:
pickler = pickle.Pickler(file)
pickler.dump(data)

def load_data(self):
with open(self.filename, 'rb') as file:
unpickler = pickle.Unpickler(file)
return unpickler.load()

# 使用方式
helper = PickleHelper('data.pkl')
helper.save_data(['apple', 'banana', 'cherry'])
loaded_data = helper.load_data()
print("加載的數據:", loaded_data)

這個 PickleHelper 類為序列化提供了更面向對象的方法,這在大型項目中可能非常有用。

醃漬自定義類對象

現在,讓我們來處理一些更進階的東西——醃漬自定義類對象。想象我們有一個 Person 類:

import pickle

class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def greet(self):
return f"你好,我的名字是 {self.name} 我 {self.age} 歲。"

# 創建一個 Person 對象
alice = Person("Alice", 30)

# 醃漬對象
with open('person.pkl', 'wb') as file:
pickle.dump(alice, file)

# 從醃漬中取對象
with open('person.pkl', 'rb') as file:
loaded_alice = pickle.load(file)

print(loaded_alice.greet())  # 輸出:你好,我的名字是 Alice 我 30 歲。

這不是很酷嗎?我們剛剛將整個人打包到一個文件中,然後又將其取出!

使用 JSON 進行序列化

當然,Pickle 非常適合 Python 特有的序列化,但有時我們需要與其他語言或系統互動。這就是 JSON 派上用場的地方。它就像數據的通用語言:

import json

# 要序列化的數據
data = {
"name": "Bob",
"age": 35,
"city": "New York",
"hobbies": ["閱讀", "游泳", "編程"]
}

# 序列化為 JSON
json_string = json.dumps(data, indent=4)
print("JSON 字符串:", json_string)

# 從 JSON 反序列化
parsed_data = json.loads(json_string)
print("解析後的數據:", parsed_data)

JSON 對於網頁應用程式和 API 特別有用,因為它在不同的平台上有廣泛的支持。

使用 YAML 進行序列化

最後但同樣重要的是,讓我們看看 YAML。YAML 以其人類可讀性而聞名,是配置文件的理想選擇:

import yaml

# 要序列化的數據
data = {
"name": "Charlie",
"age": 40,
"pets": ["狗", "貓", "魚"],
"address": {
"street": "123 Main St",
"city": "Anytown"
}
}

# 序列化為 YAML
yaml_string = yaml.dump(data, default_flow_style=False)
print("YAML 字符串:\n", yaml_string)

# 從 YAML 反序列化
parsed_data = yaml.safe_load(yaml_string)
print("解析後的數據:", parsed_data)

YAML 的格式對眼睛來說很容易,使得它非常適合人類需要經常閱讀或編輯的數據。

就是這樣,我親愛的學生們!我們已經解開了 Python 中序列化的概念,從 Pickle 的基礎到 JSON 的多用途以及 YAML 的可讀性。請記住,每種方法都有其優勢,所以選擇最適合你需求的那一個。

當我們結束這堂課時,我想起了偉大的電腦科學家 Alan Kay 的一句話:“簡單的事情應該是簡單的,複雜的事情應該是可能的。” Python 中的序列化完美地體現了這個原則,為日常任務提供簡單的解決方案,同時也能夠處理複雜的數據操作。

繼續練習,保持好奇心,並編程愉快!

Credits: Image by storyset