Python Cookbook-7.2 使用 pickle 和 cPickle 模塊序列化數據

任務

你想以某種可以接受的速度序列化和重建Python 數據結構,這些數據既包括基本Python 對象也包括類和實例。

解決方案

如果你不想假設你的數據完全由基本 Python 對象組成,或者需要在不同的 Python 版本之間移植,再或者需要將序列化后的形態作為文本傳遞,那么最好的序列化數據的方法是 cPickle 模塊(pickle 模塊是完全用 Python 實現的,而且完全可以替代 cPickle,但問題是它比較慢,除非你沒有cPickle用,不然它并不是最好的選擇)。舉個例子假設你有:

data = {12:'twelve', 'feep':list('ciao'), 1.23:4+5j, (1,2,3):u'wer'}

可以將 data 序列化為文本字符串:

import cPickle
text = cPickle.dumps(data)

或者轉化為二進制串,這種選擇通常更快而且更節省空間:

bytes = cPickle.dumps(data,2)

現在,可以將text和 bytes按照意愿進行各種處理(比如,通過網絡傳遞,作為BLOB放入數據庫中,見 7.10節、7.11節和 7.12節),只要你不修改 text和 bytes 本身。對于bytes 而言,那意味著應該保證其二進制字節序不被改變,對于text 而言,應該保證它的文本結構不被改變,包括換行符。之后,無論在什么計算機體系結構之下,無論用什么版本的 Python,你都可以重新構建出那些數據:

redata1 = cPickle.loads(text)
redata2 = cPickle.loads(bytes)

每個調用創建出來的數據結構都等于原數據。比較特別的是,字典的鍵在原數據和新建數據中的順序都是任意的,但這個順序本身是有意義的,因此也會被保存。無須告訴 cPickle.loads 原先的 dumps 是否使用了文本模式(這是默認的模式,可以由一些很老的 Python 版本讀取)或二進制模式(快速目緊湊),loads 可以通過檢查參數的內容自行判斷。

當你希望將數據寫入文件時,可以直接使用cPickle的dump函數,它允許你將多個數據結構一個接一個地寫入到同一個文件:

ouf = open('datafile.txt','w')
cPickle.dump(data,ouf)
cPickle.dump('some string',ouf)
cPickle.dump(range(19),ouf)
ouf.close()

一旦你做完這些事,就可以從 datafle.txt 中以相同的順序一個接一個地恢復原來的數據結構:

inf = open('datafile.txt')
a = cPickle.load(inf)
b = cPickle.load(inf)
c = cPickle.load(inf)
inf.close()

還可以給 cPickle.dump 傳遞值為2的第三個參數,這相當于告訴 cPickle.dump 以二進制的形式(快速且緊湊)序列化數據,但同時數據文件也必須以二進制模式打開,而不能是默認的文本模式,無論你是想寫入或是取出數據。

討論

Python 提供了幾種方法來序列化數據(比如,將數據轉化為字節串,存入磁盤或數據庫,或者通過網絡傳遞)以及從序列化形式重新構建數據。最好的方式是使用cPickle模塊。它有一個純 Python 的對應物,叫做 pickle(cPickle 模塊是用C編寫的 Python 擴展),但速度就慢得多了,只有在沒有cPickle 的情況下才應該考慮使用它(比如,將Python 移植到容量很小的手機中,必須節省每一個字節,所以只能安裝那些完全不可或缺的 Python 標準庫的子集)。然而,在任何能夠使用 pickle 的地方,都可以將其替換為 cPickle:可以用其中的一個將數據序列化,用另一個恢復并重新構建數據,而不會有任何問題。

cPickle 支持絕大多數的基本數據類型(如字典、列表、元組、數字、字符串)以及它們的各種組合形式,同時也支持類和實例。而對類和實例所做的處理僅僅涉及到數據與代碼無關(cPikle 對象并不知道怎樣序列化代碼對象,這可能是因為在不同的 Python發行版之間的可移植性完全無法保證,因此序列化代碼對象意義不大。如果你不需要考慮跨版本問題的話,可參看7.6節介紹的對代碼對象的序列化方法)。7.4節還有更多的用 cPickle 處理類和實例的細節。

cPickle 保證了在不同 Python 發行版之間的兼容性,也保證了對于特定計算機體系結構的獨立性。即使你升級了你的Python 發行版,通過cPickle處理的序列化數據仍然可以被讀取,而且即使在不同的計算機上,這種序列化和反序列化操作也是保證可用的。

cPickle 的 dumps 函數接受任何 Python 數據結構作為參數,并返回一個字符串。如果用2 作為 dumps 的第二個參數,dumps 將返回一個字節串:操作速度會更快,而且產生的串長度會更短。可以給 loads函數傳遞字符串或者字節串,它都將返回一個Python 數據結構,此數據等同于(=)原來的數據。在 dumps 和 loads 調用之間,可以以任意方式處置那個字符串或字節串,比如通過網絡傳輸,存入數據庫并讀取,或者加密之后再解密。只要這個串本身的結構沒有被改變,loads都能夠正確地讀取(即使是在不同的平臺上,或者用更新的發行的版本)。如果需要用老版本(早于2.3)的Python 處理數據,可考慮用1作為第二個參數:其操作速度會比較慢,產生的結果串也不如用2作參數產生的串緊湊短小,但這個串可以被老版本和最新的 Python,甚至以后的Python版本讀取。

當需要將數據存入文件時,可以使用cPickle的dump函數,它接受兩個參數:需要處理的數據結構和一個打開的文件對象,或者一個類文件對象。如果文件是以二進制輸入輸出方式打開的,而不是默認方式(文本模式),可以把2作為它的第三個參數,明確要求使用二進制格式,這樣速度更快也更緊湊(或用1作為第三個參數來產生結果串,這樣速度不快,要求的空間也更多,但是它能夠被很老的,甚至早于 2.3的 Python版本讀取)。dump 優于 dumps 的地方在于,通過 dump,可以進行幾個調用,一個接一個地將不同的數據結構存入到同一個打開的文件。每個數據結構在存入時還會帶有附加的信息,如這個串的長度。因此,當你以后打開此文件讀取數據(二進制讀取,如果你當初要求以二進制格式存入的話)并反復調用cPickle.load 時,可將文件作為其參數,根據順序一個接一個地構建出原來的數據結構。而load 的返回值,就像 loads 的返回值一樣,是一個完全等同于原數據的新的數據結構。

那些習慣于其他語言和庫提供的“序列化”工具的用戶可能會問,對于想要序列化和反序列化的對象的大小,pickle會不會有什么限制。答案是:沒有。你的計算機的內存可能是唯一的限制,如果你的計算機的內存非常大,pickle 在實踐中幾乎是沒有限制的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/78570.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78570.shtml
英文地址,請注明出處:http://en.pswp.cn/web/78570.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025.5.5總結

今日感悟:這假期就這樣結束了,玩了一次滑板,打掃了一次租房,出去逛了一次街,看完了一本書,追了一部劇。既沒有家人,也沒有能一同暢飲的同學,更沒有對象,顯得確實有些孤獨…

MySQL | DQL語句-連接查詢

MySQL | DQL語句-連接查詢 🪄個人博客:https://vite.xingji.fun 什么是連接查詢 從一張表中查詢數據稱為單表查詢。從兩張或更多張表中聯合查詢數據稱為多表查詢,又叫做連接查詢。什么時候需要使用連接查詢? 比如這樣的需求&…

Vite簡單介紹

Vite 是一個現代化的前端構建工具,由 Vue.js 的創始人 Evan You 開發,旨在提供更快的開發體驗和更高效的構建流程。它的名字來源于法語單詞“vite”,意為“快速”,這也反映了它的核心優勢——極速的冷啟動和熱模塊替換&#xff08…

C語言-回調函數

回調函數 通過函數指針調用函數,而這個被調用的函數稱為回調函數 回調函數是C語言中一種強大的機制,允許將函數作為參數傳遞給其他函數,從而在特定時機由后者調用。它的核心在于函數指針的使用 以下是回調函數的使用例子 先創建好一個函數…

啟發式算法-禁忌搜索算法

禁忌搜索是一種可以用于解決組合優化問題的啟發式算法,通過引入記憶機制跳出局部最優,避免重復搜索。該算法從一個初始解開始,通過鄰域搜索策略來尋找當前解的鄰域解,并在鄰域解中選擇一個最優解作為下一次迭代的當前解&#xff0…

Python 整理3種查看神經網絡結構的方法

1. 網絡結構代碼 import torch import torch.nn as nn# 定義Actor-Critic模型 class ActorCritic(nn.Module):def __init__(self, state_dim, action_dim):super(ActorCritic, self).__init__()self.actor nn.Sequential(# 全連接層,輸入維度為 state_dim&#xf…

Linux 查詢CPU飆高的原因

獲取進程ID ps -efgrep xxxx查詢占用最高的線程ID top -Hp 線程ID線程ID 轉 16進制數 printf 0x%x\n 線程ID基于jstack工具 跟蹤堆棧定位代碼位置 jstack 進程ID | grep 16禁止線程ID -A 20

Oracle OCP認證考試考點詳解083系列09

題記: 本系列主要講解Oracle OCP認證考試考點(題目),適用于19C/21C,跟著學OCP考試必過。 41. 第41題: 題目 解析及答案: 關于應用程序容器,以下哪三項是正確的? A) 它可以包含單個…

GESP2024年3月認證C++八級( 第二部分判斷題(1-5))

孫子定理參考程序&#xff1a; #include <iostream> #include <vector> using namespace std;// 擴展歐幾里得算法&#xff1a;用于求逆元 int extendedGCD(int a, int b, int &x, int &y) {if (b 0) {x 1; y 0;return a;}int x1, y1;int gcd extende…

C 語言比較運算符:程序如何做出“判斷”?

各類資料學習下載合集 ??https://pan.quark.cn/s/8c91ccb5a474?? 在編寫程序時,我們經常需要根據不同的條件來執行不同的代碼。比如,如果一個分數大于 60 分,就判斷為及格;如果用戶的年齡小于 18 歲,就禁止訪問某個內容等等。這些“判斷”的核心,就依賴于程序能夠比…

WITH在MYSQL中的用法

WITH 子句&#xff08;也稱為公共表表達式&#xff0c;Common Table Expression&#xff0c;簡稱 CTE&#xff09;是 SQL 中一種強大的查詢構建工具&#xff0c;它可以顯著提高復雜查詢的可讀性和可維護性。 一、基本語法結構 WITH cte_name AS (SELECT ... -- 定義CTE的查詢…

多序列比對軟件MAFFT介紹

MAFFT(Multiple Alignment using Fast Fourier Transform)是一款廣泛使用且高效的多序列比對軟件,由日本京都大學的Katoh Kazutaka等人開發,最早發布于2002年,并持續迭代優化至今。 它支持從幾十條到上萬條核酸或蛋白質序列的快速比對,同時在準確率和計算效率之間提供靈…

APP 設計中的色彩心理學:如何用色彩提升用戶體驗

在數字化時代&#xff0c;APP 已成為人們日常生活中不可或缺的一部分。用戶在打開一個 APP 的瞬間&#xff0c;首先映入眼簾的便是其色彩搭配&#xff0c;而這些色彩并非只是視覺上的裝飾&#xff0c;它們蘊含著強大的心理暗示力量&#xff0c;能夠潛移默化地影響用戶的情緒、行…

Compose 中使用 WebView

在 Jetpack Compose 中&#xff0c;我們可以使用 AndroidView 組件來集成傳統的 Android WebView。以下是幾種實現方式&#xff1a; 基礎 WebView 實現 Composable fun WebViewScreen(url: String) {AndroidView(factory { context ->WebView(context).apply {// 設置布局…

2025年01月03日美蜥(杭州普瑞兼職)二面

目錄 為何 nginx 可以實現跨域請求&#xff0c;原理是什么為何 nodejs 可以實現跨域請求&#xff0c;原理是什么瀏覽器的請求頭有哪些瀏覽器的響應頭有哪些瀏覽器輸入網址后發生什么http 協議和 https 有什么區別你的核心優勢是什么瀏覽器緩存機制https 的加密機制tcp 的三次握…

如何選擇合適的光源?

目錄 工業相機光源類型全面指南 1. 環形光源及其變體 高角度環形光源 優點 缺點 典型應用場景 低角度環形光源&#xff08;暗場照明&#xff09; 優點 缺點 典型應用場景 2. 條形光源與組合照明系統 技術特點 組合條形光源 優點 缺點 典型應用場景 3. 同軸光源…

「OC」源碼學習——對象的底層探索

「OC」源碼學習——對象的底層探索 前言 上次我們說到了源碼里面的調用順序&#xff0c;現在我們繼續了解我們上一篇文章沒有講完的關于對象的內容函數&#xff0c;完整了解對象的產生對于isa賦值以及內存申請的內容 函數內容 先把_objc_rootAllocWithZone函數的內容先貼上…

【C++指南】STL list容器完全解讀(一):從入門到掌握基礎操作

. &#x1f493; 博客主頁&#xff1a;倔強的石頭的CSDN主頁 &#x1f4dd;Gitee主頁&#xff1a;倔強的石頭的gitee主頁 ? 文章專欄&#xff1a;《C指南》 期待您的關注 文章目錄 一、初識list容器1.1 什么是list&#xff1f;1.2 核心特性1.3 典型應用場景 二、核心成員函數…

labelimg快捷鍵

一、核心標注快捷鍵 ?W?&#xff1a;調出標注十字架&#xff0c;開始繪制矩形框&#xff08;最常用功能&#xff09;?A/D?&#xff1a;切換上一張(A)或下一張(D)圖片&#xff0c;實現快速導航?Del?&#xff1a;刪除當前選中的標注框 二、文件操作快捷鍵 ?CtrlS?&…

linux-文件操作

在 Linux 系統中&#xff0c;文件操作與管理是日常使用和系統管理的重要組成部分。下面將詳細介紹文件的復制、移動、鏈接創建&#xff0c;以及文件查找、文本處理、排序、權限管理等相關知識。 一、文件的復制 在 Linux 里&#xff0c;cp 命令可用于復制文件或目錄&#xff…