python中pickle庫用法舉例詳解
pickle庫
pickle
是 Python 標(biāo)準(zhǔn)庫中的一個(gè)模塊,它可以將 Python 對象(如列表、字典、類實(shí)例等)轉(zhuǎn)換為字節(jié)流,這個(gè)過程稱為“序列化”;反之,也可以將字節(jié)流轉(zhuǎn)換回 Python 對象,這個(gè)過程稱為“反序列化”。:
1. 導(dǎo)入 pickle 模塊
在使用 pickle
模塊之前,需要先導(dǎo)入它:
import pickle
2. 序列化(pickle.dump() 和 pickle.dumps())
2.1 pickle.dumps()
pickle.dumps()
函數(shù)用于將 Python 對象序列化為字節(jié)流,返回一個(gè)字節(jié)對象。
import pickle data = {'name': 'Alice', 'age': 25} # 序列化對象 serialized_data = pickle.dumps(data) print(type(serialized_data)) # <class 'bytes'> print(serialized_data)
2.2 pickle.dump()
pickle.dump()
函數(shù)用于將 Python 對象序列化并直接寫入文件對象。
import pickle data = [1, 2, 3, 4, 5] # 打開一個(gè)文件以二進(jìn)制寫入模式 with open('data.pickle', 'wb') as file: # 將對象序列化并寫入文件 pickle.dump(data, file)
3. 反序列化(pickle.load() 和 pickle.loads())
3.1 pickle.loads()
pickle.loads()
函數(shù)用于將字節(jié)流反序列化為 Python 對象。
import pickle data = {'name': 'Bob', 'age': 30} serialized_data = pickle.dumps(data) # 反序列化字節(jié)流 deserialized_data = pickle.loads(serialized_data) print(deserialized_data) # {'name': 'Bob', 'age': 30}
3.2 pickle.load()
pickle.load()
函數(shù)用于從文件對象中讀取字節(jié)流并反序列化為 Python 對象。
import pickle # 打開一個(gè)文件以二進(jìn)制讀取模式 with open('data.pickle', 'rb') as file: # 從文件中讀取并反序列化對象 loaded_data = pickle.load(file) print(loaded_data) # [1, 2, 3, 4, 5]
4. 支持的對象類型
pickle
可以處理大多數(shù) Python 內(nèi)置對象類型,包括:
- 布爾值、整數(shù)、浮點(diǎn)數(shù)、復(fù)數(shù)等基本數(shù)據(jù)類型。
- 字符串、字節(jié)、字節(jié)數(shù)組。
- 列表、元組、集合、字典等容器類型。
- 函數(shù)(僅限于全局作用域內(nèi)定義的函數(shù))。
- 類(僅限于全局作用域內(nèi)定義的類)和類實(shí)例。
5. 不支持的對象類型
- 生成器、迭代器、文件對象等。
- 部分內(nèi)置對象(如
open()
返回的文件對象、sockets
對象等)。
6. 協(xié)議版本
pickle
支持多個(gè)協(xié)議版本,不同的協(xié)議版本在性能和兼容性上有所不同??梢酝ㄟ^ pickle.HIGHEST_PROTOCOL
獲取當(dāng)前 Python 版本支持的最高協(xié)議版本,也可以在 dump()
和 dumps()
函數(shù)中指定協(xié)議版本。
import pickle data = {'key': 'value'} # 使用最高協(xié)議版本進(jìn)行序列化 serialized_data = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
7. 安全性問題
pickle
反序列化操作存在安全風(fēng)險(xiǎn),因?yàn)樗梢詧?zhí)行任意代碼。如果從不可信的源接收 pickle
數(shù)據(jù),可能會(huì)導(dǎo)致代碼注入攻擊。因此,在反序列化數(shù)據(jù)時(shí),要確保數(shù)據(jù)來源是可信的。
8. 與 json 模塊的比較
- 數(shù)據(jù)格式:
pickle
序列化后的數(shù)據(jù)是二進(jìn)制格式,而json
序列化后的數(shù)據(jù)是文本格式。 - 支持的對象類型:
pickle
可以處理更廣泛的 Python 對象類型,而json
只能處理基本數(shù)據(jù)類型和部分容器類型。 - 安全性:
json
反序列化相對安全,因?yàn)樗荒芴幚砑償?shù)據(jù),而pickle
反序列化存在安全風(fēng)險(xiǎn)。
9. 示例:序列化和反序列化自定義類實(shí)例
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è) Person 類的實(shí)例 person = Person('Charlie', 35) # 序列化實(shí)例 serialized_person = pickle.dumps(person) # 反序列化實(shí)例 deserialized_person = pickle.loads(serialized_person) print(deserialized_person) # Person(name=Charlie, age=35)
序列化
序列化是將對象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问剑ㄈ缱止?jié)序列、文本等)的過程。在不同的應(yīng)用場景中,序列化發(fā)揮著重要的作用,以下從幾個(gè)方面詳細(xì)介紹序列化的作用:
1. 數(shù)據(jù)持久化
- 存儲(chǔ)對象到磁盤:在許多應(yīng)用程序中,需要將程序運(yùn)行過程中的對象保存到磁盤上,以便在程序下次啟動(dòng)時(shí)能夠恢復(fù)這些對象的狀態(tài)。例如,一個(gè)游戲程序可能需要保存玩家的游戲進(jìn)度,包括玩家的角色信息、關(guān)卡進(jìn)度、道具列表等。通過序列化,可以將這些對象轉(zhuǎn)換為字節(jié)流,然后存儲(chǔ)到文件中。下次游戲啟動(dòng)時(shí),再從文件中讀取字節(jié)流并反序列化,恢復(fù)玩家的游戲進(jìn)度。
import pickle class Player: def __init__(self, name, level): self.name = name self.level = level # 創(chuàng)建一個(gè)玩家對象 player = Player("Alice", 10) # 將玩家對象序列化并保存到文件 with open('player_data.pickle', 'wb') as file: pickle.dump(player, file) # 下次啟動(dòng)程序時(shí),從文件中讀取并反序列化對象 with open('player_data.pickle', 'rb') as file: loaded_player = pickle.load(file) print(f"Player name: {loaded_player.name}, Level: {loaded_player.level}")
- 數(shù)據(jù)庫存儲(chǔ):在數(shù)據(jù)庫中存儲(chǔ)復(fù)雜的對象時(shí),序列化也非常有用。有些數(shù)據(jù)庫(如 NoSQL 數(shù)據(jù)庫)可以直接存儲(chǔ)二進(jìn)制數(shù)據(jù),通過將對象序列化后存儲(chǔ)到數(shù)據(jù)庫中,可以方便地保存和檢索對象信息。
2. 數(shù)據(jù)傳輸
- 網(wǎng)絡(luò)通信:在網(wǎng)絡(luò)編程中,不同的計(jì)算機(jī)或進(jìn)程之間需要進(jìn)行數(shù)據(jù)交換。由于網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)必須是二進(jìn)制形式,因此需要將對象序列化為字節(jié)流后才能在網(wǎng)絡(luò)上傳輸。例如,在客戶端 - 服務(wù)器架構(gòu)中,客戶端可能需要將用戶的請求對象(如登錄請求、查詢請求等)序列化后發(fā)送給服務(wù)器,服務(wù)器接收到字節(jié)流后再進(jìn)行反序列化,解析出請求信息并進(jìn)行相應(yīng)的處理。常見的網(wǎng)絡(luò)協(xié)議如 HTTP、TCP 等都可以傳輸序列化后的數(shù)據(jù)。
import socket import pickle # 服務(wù)器端 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 8888)) server_socket.listen(1) print("Waiting for a connection...") conn, addr = server_socket.accept() print(f"Connected by {addr}") # 接收序列化的數(shù)據(jù) data = conn.recv(1024) # 反序列化數(shù)據(jù) received_object = pickle.loads(data) print(f"Received object: {received_object}") conn.close() # 客戶端 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 8888)) # 要發(fā)送的對象 data_to_send = {'message': 'Hello, server!'} # 序列化對象 serialized_data = pickle.dumps(data_to_send) # 發(fā)送序列化的數(shù)據(jù) client_socket.sendall(serialized_data) client_socket.close()
- 進(jìn)程間通信(IPC):在多進(jìn)程編程中,不同的進(jìn)程之間需要進(jìn)行數(shù)據(jù)交換。序列化可以將對象轉(zhuǎn)換為可以在進(jìn)程間傳輸?shù)母袷?,從而?shí)現(xiàn)進(jìn)程間的通信。例如,在 Python 的
multiprocessing
模塊中,進(jìn)程之間可以通過管道(Pipe
)、隊(duì)列(Queue
)等方式進(jìn)行通信,這些通信機(jī)制內(nèi)部會(huì)使用序列化和反序列化來處理對象的傳輸。
3. 數(shù)據(jù)共享與協(xié)作
- 分布式系統(tǒng):在分布式系統(tǒng)中,不同的節(jié)點(diǎn)(計(jì)算機(jī)或服務(wù)器)之間需要共享數(shù)據(jù)和協(xié)同工作。序列化可以將對象在不同節(jié)點(diǎn)之間進(jìn)行傳輸和共享,使得各個(gè)節(jié)點(diǎn)能夠處理和操作相同的數(shù)據(jù)。例如,在一個(gè)分布式計(jì)算系統(tǒng)中,主節(jié)點(diǎn)可以將任務(wù)對象序列化后分發(fā)給各個(gè)工作節(jié)點(diǎn),工作節(jié)點(diǎn)接收到任務(wù)對象后進(jìn)行反序列化,然后執(zhí)行相應(yīng)的任務(wù)。
- 跨語言交互:在一些跨語言的應(yīng)用場景中,不同的編程語言可能需要共享數(shù)據(jù)。通過選擇一種通用的序列化格式(如 JSON、XML 等),可以實(shí)現(xiàn)不同語言之間的數(shù)據(jù)交互。例如,一個(gè) Python 程序可以將數(shù)據(jù)序列化為 JSON 格式,然后將 JSON 數(shù)據(jù)發(fā)送給一個(gè) Java 程序,Java 程序再將 JSON 數(shù)據(jù)反序列化后進(jìn)行處理。
4. 緩存和優(yōu)化
- 緩存機(jī)制:在一些應(yīng)用程序中,為了提高性能,會(huì)使用緩存來存儲(chǔ)經(jīng)常使用的數(shù)據(jù)。通過將對象序列化后存儲(chǔ)在緩存中,可以減少對象的創(chuàng)建和初始化時(shí)間。當(dāng)需要使用這些數(shù)據(jù)時(shí),直接從緩存中讀取并反序列化,避免了重復(fù)計(jì)算和數(shù)據(jù)庫查詢。例如,在 Web 應(yīng)用程序中,可以使用緩存(如 Redis)來存儲(chǔ)用戶的會(huì)話信息,將用戶會(huì)話對象序列化后存儲(chǔ)在 Redis 中,下次用戶訪問時(shí)直接從 Redis 中讀取并反序列化,提高響應(yīng)速度。
- 數(shù)據(jù)壓縮:序列化過程中可以對數(shù)據(jù)進(jìn)行壓縮,減少數(shù)據(jù)的存儲(chǔ)空間和傳輸帶寬。例如,一些序列化庫(如 Protocol Buffers)支持?jǐn)?shù)據(jù)壓縮功能,通過將對象序列化并壓縮后存儲(chǔ)或傳輸,可以節(jié)省大量的資源。
綜上所述,序列化在數(shù)據(jù)持久化、傳輸、共享和緩存等方面都有著重要的作用,是現(xiàn)代軟件開發(fā)中不可或缺的技術(shù)之一。
總結(jié)
到此這篇關(guān)于python中pickle庫用法的文章就介紹到這了,更多相關(guān)python pickle庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pandas之query方法和sample隨機(jī)抽樣操作
這篇文章主要介紹了pandas之query方法和sample隨機(jī)抽樣操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03Tensorflow之MNIST CNN實(shí)現(xiàn)并保存、加載模型
這篇文章主要為大家詳細(xì)介紹了Tensorflow之MNIST CNN實(shí)現(xiàn)并保存、加載模型,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06