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