Python?pickle?二進(jìn)制序列化和反序列化及數(shù)據(jù)持久化詳解
模塊 pickle 實(shí)現(xiàn)了對(duì)一個(gè) Python 對(duì)象結(jié)構(gòu)的二進(jìn)制序列化和反序列化。 "pickling" 是將 Python 對(duì)象及其所擁有的層次結(jié)構(gòu)轉(zhuǎn)化為一個(gè)字節(jié)流的過(guò)程,而 "unpickling" 是相反的操作,會(huì)將(來(lái)自一個(gè) binary file 或者 bytes-like object 的)字節(jié)流轉(zhuǎn)化回一個(gè)對(duì)象層次結(jié)構(gòu)。 pickling(和 unpickling)也被稱(chēng)為“序列化”, “編組” 1 或者 “平面化”。而為了避免混亂,此處采用術(shù)語(yǔ) “封存 (pickling)” 和 “解封 (unpickling)”。
pickle模塊 并不安全。 你只應(yīng)該對(duì)你信任的數(shù)據(jù)進(jìn)行 unpickle 操作。
構(gòu)建惡意的 pickle 數(shù)據(jù)來(lái) 在解封時(shí)執(zhí)行任意代碼 是可能的。 絕對(duì)不要對(duì)不信任來(lái)源的數(shù)據(jù)和可能被篡改過(guò)的數(shù)據(jù)進(jìn)行解封。
請(qǐng)考慮使用 hmac 來(lái)對(duì)數(shù)據(jù)進(jìn)行簽名,確保數(shù)據(jù)沒(méi)有被篡改。
在你處理不信任數(shù)據(jù)時(shí),更安全的序列化格式如 json 可能更為適合。
與 json 模塊的比較
在 pickle 協(xié)議和 JSON (JavaScript Object Notation) 之間有著本質(zhì)上的差異:
- JSON 是一個(gè)文本序列化格式(它輸出 unicode 文本,盡管在大多數(shù)時(shí)候它會(huì)接著以 utf-8 編碼),而 pickle 是一個(gè)二進(jìn)制序列化格式;
- JSON 是我們可以直觀閱讀的,而 pickle 不是;
- JSON是可互操作的,在Python系統(tǒng)之外廣泛使用,而pickle則是Python專(zhuān)用的;
- 默認(rèn)情況下,JSON 只能表示 Python 內(nèi)置類(lèi)型的子集,不能表示自定義的類(lèi);但 pickle 可以表示大量的 Python 數(shù)據(jù)類(lèi)型(可以合理使用 Python 的對(duì)象內(nèi)省功能自動(dòng)地表示大多數(shù)類(lèi)型,復(fù)雜情況可以通過(guò)實(shí)現(xiàn) specific object APIs 來(lái)解決)。
- 不像pickle,對(duì)一個(gè)不信任的JSON進(jìn)行反序列化的操作本身不會(huì)造成任意代碼執(zhí)行漏洞。
Pickle的基本用法
序列化(Pickling)
要將Python對(duì)象序列化為二進(jìn)制數(shù)據(jù),可以使用pickle.dump()函數(shù)。以下是一個(gè)簡(jiǎn)單的示例,將一個(gè)Python列表保存到文件中:
import pickle
data = [1, 2, 3, 4, 5]
# 打開(kāi)一個(gè)文件以寫(xiě)入二進(jìn)制數(shù)據(jù)
with open('data/data.pkl', 'wb') as file:
pickle.dump(data, file)在上述代碼中,使用pickle.dump()函數(shù)將data列表序列化為二進(jìn)制數(shù)據(jù),并將其保存到名為data.pkl的文件中。參數(shù)'wb'表示以二進(jìn)制寫(xiě)入模式打開(kāi)文件。
反序列化(Unpickling)
要從文件中加載并反序列化二進(jìn)制數(shù)據(jù),可以使用pickle.load()函數(shù)。以下是加載data.pkl文件并還原Python對(duì)象的示例:
import pickle
# 打開(kāi)文件以讀取二進(jìn)制數(shù)據(jù)
with open('data/data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print("反序列化 %s" % loaded_data)在上述代碼中,使用pickle.load()函數(shù)從data.pkl文件中加載數(shù)據(jù),并將其還原為Python對(duì)象。
Pickle的工作原理
pickle模塊的工作原理涉及到將Python對(duì)象轉(zhuǎn)換為一種可序列化的中間格式,然后再將該中間格式序列化為二進(jìn)制數(shù)據(jù)。這個(gè)中間格式是一個(gè)自包含的表示對(duì)象的字典,其中包含了對(duì)象的數(shù)據(jù)和其類(lèi)型信息。
當(dāng)使用pickle.dump()序列化對(duì)象時(shí),pickle 模塊首先創(chuàng)建一個(gè)包含對(duì)象數(shù)據(jù)和類(lèi)型信息的中間字典。然后,它將該字典轉(zhuǎn)換為二進(jìn)制數(shù)據(jù)。反序列化時(shí),pickle模塊將二進(jìn)制數(shù)據(jù)還原為中間字典,然后再?gòu)淖值渲羞€原Python對(duì)象。
這種方法使pickle模塊非常靈活,因?yàn)樗梢孕蛄谢瘞缀跛蠵ython對(duì)象,包括自定義對(duì)象,只要它們可以在中間字典中表示。
Pickle的適用場(chǎng)景
pickle模塊在以下情況下非常有用:
- 數(shù)據(jù)持久化:你可以使用pickle將Python對(duì)象保存到文件中,以便稍后讀取。這對(duì)于保存模型、配置文件、數(shù)據(jù)緩存等非常有用。
- 數(shù)據(jù)傳輸:你可以使用pickle將Python對(duì)象序列化并通過(guò)網(wǎng)絡(luò)傳輸,以便不同的Python程序之間共享數(shù)據(jù)。
- 對(duì)象復(fù)制:你可以使用pickle將Python對(duì)象進(jìn)行深拷貝,以便創(chuàng)建對(duì)象的獨(dú)立副本,而不是引用原始對(duì)象。
- 測(cè)試和調(diào)試:pickle也用于創(chuàng)建模擬數(shù)據(jù),以便進(jìn)行測(cè)試和調(diào)試。
Pickle的注意事項(xiàng)
盡管pickle非常方便,但在使用它時(shí)需要注意一些事項(xiàng):
- 安全性:反序列化數(shù)據(jù)時(shí)要小心,因?yàn)閜ickle可以執(zhí)行任意代碼。不要從不受信任的來(lái)源加載pickle數(shù)據(jù),以免遭受安全風(fēng)險(xiǎn)。
- 版本兼容性:在不同版本的Python之間,pickle數(shù)據(jù)的兼容性可能會(huì)有問(wèn)題。因此,確保在不同版本之間測(cè)試并驗(yàn)證pickle數(shù)據(jù)的兼容性。
- 自定義對(duì)象:一些自定義對(duì)象的序列化和反序列化可能會(huì)受到限制,因此需要額外的配置。你可能需要實(shí)現(xiàn)特定的__reduce__方法來(lái)控制對(duì)象的序列化行為。
示例代碼
以下是一個(gè)示例代碼,演示如何使用pickle模塊來(lái)序列化和反序列化一個(gè)自定義Python對(duì)象:
import pickle
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name='{self.name}', age={self.age})"
# 創(chuàng)建一個(gè)自定義對(duì)象
person = Person("Alice", 30)
# 序列化并保存到文件
with open('data/person.pkl', 'wb') as file:
pickle.dump(person, file)
# 從文件中加載并反序列化
with open('data/person.pkl', 'rb') as file:
loaded_person = pickle.load(file)
print(loaded_person) # 輸出: Person(name='Alice', age=30)在上述代碼中,我們首先定義了一個(gè)自定義類(lèi)Person,然后創(chuàng)建了一個(gè)Person對(duì)象。我們使用pickle將該對(duì)象序列化為二進(jìn)制數(shù)據(jù),然后再?gòu)亩M(jìn)制數(shù)據(jù)中反序列化還原對(duì)象。
到此這篇關(guān)于Python pickle 二進(jìn)制序列化和反序列化 - 數(shù)據(jù)持久化的文章就介紹到這了,更多相關(guān)Python pickle 二進(jìn)制序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 一文詳解python pickle中的反序列化漏洞
- Python Json與pickle模塊序列化使用介紹
- Python序列化模塊JSON與Pickle
- Python序列化模塊之pickle與json詳解
- Python數(shù)據(jù)序列化之pickle模塊
- Python使用pickle進(jìn)行序列化和反序列化的示例代碼
- Python序列化pickle模塊使用詳解
- Python序列化與反序列化pickle用法實(shí)例
- Python之?dāng)?shù)據(jù)序列化(json、pickle、shelve)詳解
- Python pickle模塊進(jìn)行序列化的實(shí)現(xiàn)示例
相關(guān)文章
一文帶你搞懂Python中鴨子類(lèi)型的原理與應(yīng)用
Python鴨子類(lèi)型是一種靈活的多態(tài)實(shí)現(xiàn)方式,不依賴(lài)?yán)^承關(guān)系,而是基于對(duì)象的行為,只要不同對(duì)象具有相同名稱(chēng)的方法,就可以被統(tǒng)一處理,下面小編就和大家詳細(xì)介紹一下它的具體應(yīng)用吧2026-04-04
Keras實(shí)現(xiàn)Vision?Transformer?VIT模型示例詳解
這篇文章主要為大家介紹了Keras實(shí)現(xiàn)Vision?Transformer?VIT模型示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Opencv圖像處理:如何判斷圖片里某個(gè)顏色值占的比例
這篇文章主要介紹了Opencv圖像處理:如何判斷圖片里某個(gè)顏色值占的比例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
Python如何在main中調(diào)用函數(shù)內(nèi)的函數(shù)方式
這篇文章主要介紹了Python如何在main中調(diào)用函數(shù)內(nèi)的函數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
Python3使用matplotlib繪圖時(shí),坐標(biāo)軸刻度不從X軸、y軸兩端開(kāi)始
這篇文章主要介紹了Python3使用matplotlib繪圖時(shí),坐標(biāo)軸刻度不從X軸、y軸兩端開(kāi)始問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
Python+Mysql實(shí)現(xiàn)登錄注冊(cè)完整代碼示例
在開(kāi)發(fā)中用戶(hù)注冊(cè)和登錄是常見(jiàn)的功能需求,這篇文章主要給大家介紹了關(guān)于Python+Mysql實(shí)現(xiàn)登錄注冊(cè)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-03-03

