Python3 pickle模塊的實(shí)現(xiàn)步驟
pickle 是 Python 的一個(gè)強(qiáng)大序列化模塊,它可以將幾乎任何 Python 對(duì)象轉(zhuǎn)換為字節(jié)流(序列化),也可以從字節(jié)流重新構(gòu)造對(duì)象(反序列化)。
1. 基本用法
1.1 序列化對(duì)象(pickling)
import pickle
data = {
'name': 'Alice',
'age': 30,
'scores': [85, 92, 88],
'is_active': True
}
# 序列化到字節(jié)對(duì)象
serialized = pickle.dumps(data)
print(serialized) # 輸出字節(jié)序列
# 序列化到文件
with open('data.pkl', 'wb') as f: # 注意是二進(jìn)制寫(xiě)入模式
pickle.dump(data, f)
1.2 反序列化對(duì)象(unpickling)
import pickle
# 首先創(chuàng)建一個(gè)示例數(shù)據(jù)對(duì)象
data = {
'name': 'Alice',
'age': 30,
'scores': [85, 92, 88],
'is_active': True
}
# 1. 序列化對(duì)象到字節(jié)(創(chuàng)建serialized變量)
serialized = pickle.dumps(data)
print("序列化后的字節(jié)數(shù)據(jù):", serialized)
# 2. 從字節(jié)對(duì)象反序列化
deserialized = pickle.loads(serialized)
print("反序列化后的數(shù)據(jù):", deserialized) # 輸出原始數(shù)據(jù)
# 3. 序列化到文件
with open('data.pkl', 'wb') as f: # 注意是二進(jìn)制寫(xiě)入模式
pickle.dump(data, f)
# 4. 從文件反序列化
with open('data.pkl', 'rb') as f: # 注意是二進(jìn)制讀取模式
loaded_data = pickle.load(f)
print("從文件加載的數(shù)據(jù):", loaded_data)
2. 可序列化的對(duì)象類(lèi)型
pickle 可以序列化大多數(shù) Python 對(duì)象,包括:
- 基本數(shù)據(jù)類(lèi)型(int, float, bool, str 等)
- 容器類(lèi)型(list, tuple, dict, set)
- 函數(shù)和類(lèi)(只序列化名稱(chēng),不序列化代碼)
- 類(lèi)的實(shí)例(包括自定義類(lèi))
- 模塊級(jí)函數(shù)和類(lèi)
3. 高級(jí)特性
3.1 自定義類(lèi)的序列化
import pickle
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person(name='{self.name}', age={self.age})"
alice = Person('Alice', 30)
# 序列化自定義類(lèi)實(shí)例
with open('person.pkl', 'wb') as f:
pickle.dump(alice, f)
# 反序列化
with open('person.pkl', 'rb') as f:
loaded_person = pickle.load(f)
print(loaded_person) # Person(name='Alice', age=30)
3.2 序列化協(xié)議版本
pickle 有多個(gè)協(xié)議版本,可以通過(guò) protocol 參數(shù)指定:
# 使用最高效的協(xié)議版本(Python 3.8+默認(rèn)使用協(xié)議4) pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL) # 可用的協(xié)議版本: # 0 - 原始ASCII協(xié)議(兼容舊版本) # 1 - 舊二進(jìn)制格式 # 2 - Python 2.3引入 # 3 - Python 3.0引入(默認(rèn)Python 3.0-3.7) # 4 - Python 3.4引入(默認(rèn)Python 3.8+) # 5 - Python 3.8引入(支持帶外數(shù)據(jù))
4. 安全注意事項(xiàng)
?? 重要警告:pickle 反序列化可以執(zhí)行任意代碼,永遠(yuǎn)不要反序列化不受信任來(lái)源的數(shù)據(jù)!
# 不安全的做法(可能執(zhí)行惡意代碼) malicious_data = b"cos\nsystem\n(S'rm -rf /'\ntR." # 模擬惡意pickle數(shù)據(jù) # pickle.loads(malicious_data) # 危險(xiǎn)!會(huì)執(zhí)行系統(tǒng)命令
安全替代方案:
- 對(duì)于不受信任的數(shù)據(jù),使用
json模塊 - 或者使用
ast.literal_eval()處理簡(jiǎn)單數(shù)據(jù)結(jié)構(gòu)
5. 特殊方法控制序列化
自定義類(lèi)可以通過(guò)實(shí)現(xiàn)特殊方法來(lái)控制序列化行為:
import pickle
class CustomObject:
def __init__(self, value):
self.value = value
self._internal = "secret"
# 定義序列化時(shí)要保存的屬性
def __getstate__(self):
state = self.__dict__.copy()
del state['_internal'] # 不序列化內(nèi)部屬性
return state
# 定義反序列化時(shí)的行為
def __setstate__(self, state):
self.__dict__.update(state)
self._internal = "restored" # 恢復(fù)時(shí)重新設(shè)置
obj = CustomObject(42)
serialized = pickle.dumps(obj)
new_obj = pickle.loads(serialized)
print(new_obj.value) # 42
print(new_obj._internal) # "restored"
6. 性能優(yōu)化
對(duì)于大型對(duì)象的序列化:
# 使用更高效的協(xié)議
data = [i**2 for i in range(100000)]
# 比較不同協(xié)議的大小
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
size = len(pickle.dumps(data, protocol=proto))
print(f"協(xié)議 {proto}: {size} 字節(jié)")
# 使用更快的pickle實(shí)現(xiàn)(需要安裝)
# pip install pickle5 # 對(duì)于Python < 3.8想使用協(xié)議57. 實(shí)際應(yīng)用場(chǎng)景
7.1 緩存計(jì)算結(jié)果
import pickle
import hashlib
import os
def compute_expensive_operation(params):
cache_file = f"cache_{hashlib.md5(str(params).encode()).hexdigest()}.pkl"
if os.path.exists(cache_file):
with open(cache_file, 'rb') as f:
return pickle.load(f)
# 模擬耗時(shí)計(jì)算
result = sum(x**2 for x in range(params['n']))
# 緩存結(jié)果
with open(cache_file, 'wb') as f:
pickle.dump(result, f)
return result7.2 進(jìn)程間通信
import pickle
from multiprocessing import Pool
# 在多進(jìn)程中使用pickle傳遞數(shù)據(jù)
def process_data(data):
# 處理數(shù)據(jù)...
return data * 2
if __name__ == '__main__':
data = [1, 2, 3, 4, 5]
with Pool() as pool:
results = pool.map(process_data, data)
print(results) # [2, 4, 6, 8, 10]
8. 替代方案比較
| 特性 | pickle | json | marshal | shelve |
|---|---|---|---|---|
| 人類(lèi)可讀 | ? | ? | ? | ? |
| 跨語(yǔ)言支持 | ? | ? | ? | ? |
| 序列化復(fù)雜對(duì)象 | ? | ? | ?? | ? |
| 安全性 | ? | ? | ? | ? |
| 內(nèi)置支持 | ? | ? | ? | ? |
總結(jié)
pickle 是 Python 中最強(qiáng)大的序列化工具,適合:
- 需要保存 Python 特有對(duì)象(如自定義類(lèi)實(shí)例)
- 臨時(shí)存儲(chǔ) Python 數(shù)據(jù)
- 進(jìn)程間傳遞復(fù)雜對(duì)象
但需要注意:
- 永遠(yuǎn)不要反序列化不受信任的數(shù)據(jù)
- pickle 文件不能跨 Python 版本/實(shí)現(xiàn)(如 CPython 和 PyIron)兼容
- 對(duì)于長(zhǎng)期存儲(chǔ)或跨語(yǔ)言場(chǎng)景,考慮使用 JSON 或其他格式
到此這篇關(guān)于Python3 pickle模塊的實(shí)現(xiàn)步驟的文章就介紹到這了,更多相關(guān)Python3 pickle模塊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python面向?qū)ο笾畠?nèi)置函數(shù)相關(guān)知識(shí)總結(jié)
本次要總結(jié)的的內(nèi)置函數(shù)共8個(gè),他們都跟面向?qū)ο蟮闹R(shí)相關(guān),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
python 串行執(zhí)行和并行執(zhí)行實(shí)例
這篇文章主要介紹了python 串行執(zhí)行和并行執(zhí)行實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
python?PyAutoGUI實(shí)現(xiàn)自動(dòng)化鼠標(biāo)鍵盤(pán)等常用操作
這篇文章主要介紹了python?PyAutoGUI實(shí)現(xiàn)自動(dòng)化鼠標(biāo)鍵盤(pán)等常用操作使用實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Python實(shí)現(xiàn)將列表導(dǎo)出為Excel文件
在 Python 數(shù)據(jù)處理場(chǎng)景中,將列表(List)數(shù)據(jù)導(dǎo)出為 Excel 文件是高頻需求,本文將演示如何用 Free Spire.XLS for Python 實(shí)現(xiàn)列表轉(zhuǎn) Excel,感興趣的小伙伴可以了解下2025-12-12
Python實(shí)現(xiàn)字符串反轉(zhuǎn)的9種方法(最全)
本文主要介紹了Python實(shí)現(xiàn)字符串反轉(zhuǎn)的9種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07

