Python pickle模块学习(超级详细)
pickle提供了一個簡單的持久化功能。可以將對象以文件的形式存放在磁盤上。
pickle模塊只能在python中使用,python中幾乎所有的數據類型(列表,字典,集合,類等)都可以用pickle來序列化,
pickle序列化后的數據,可讀性差,人一般無法識別。
------------------------------------------
pickle.dump(obj, file[, protocol])
序列化對象,并將結果數據流寫入到文件對象中。參數protocol是序列化模式,默認值為0,表示以文本的形式序列化。protocol的值還可以是1或2,表示以二進制的形式序列化。
------------------------------------------
pickle.load(file)
反序列化對象。將文件中的數據解析為一個Python對象。
其中要注意的是,在load(file)的時候,要讓python能夠找到類的定義,否則會報錯:
比如下面的例子
[python]??view plain??copy
如果不注釋掉del Person的話,那么會報錯如下:
意思就是當前模塊找不到類的定義了。
--------------------------------------------------
clear_memo()
清空pickler的“備忘”。使用Pickler實例在序列化對象的時候,它會“記住”已經被序列化的對象引用,所以對同一對象多次調用dump(obj),pickler不會“傻傻”的去多次序列化。
看下面的例子:
[python]??view plain??copy
上面的代碼運行如下:
如果不注釋掉,則運行結果是第二個。如果注釋掉,那么運行結果是第一個。
主要是因為,python的pickle如果不clear_memo,則不會多次去序列化對象。
原文鏈接:點擊打開鏈接
持久性就是指保持對象,甚至在多次執行同一程序之間也保持對象。通過本文,您會對 Python對象的各種持久性機制(從關系數據庫到 Python 的 pickle以及其它機制)有一個總體認識。另外,還會讓您更深一步地了解Python 的對象序列化能力。 什么是持久性? 持久性的基本思想很簡單。假定有一個 Python 程序,它可能是一個管理日常待辦事項的程序,您希望在多次執行這個程序之間可以保存應用程序對象(待辦事項)。換句話說,您希望將對象存儲在磁盤上,便于以后檢索。這就是持久性。要達到這個目的,有幾種方法,每一種方法都有其優缺點。 例如,可以將對象數據存儲在某種格式的文本文件中,譬如 CSV 文件。或者可以用關系數據庫,譬如 Gadfly、MySQL、PostgreSQL 或者 DB2。這些文件格式和數據庫都非常優秀,對于所有這些存儲機制,Python 都有健壯的接口。 這些存儲機制都有一個共同點:存儲的數據是獨立于對這些數據進行操作的對象和程序。這樣做的好處是,數據可以作為共享的資源,供其它應用程序使用。缺點是,用這種方式,可以允許其它程序訪問對象的數據,這違背了面向對象的封裝性原則 — 即對象的數據只能通過這個對象自身的公共(public)接口來訪問。 另外,對于某些應用程序,關系數據庫方法可能不是很理想。尤其是,關系數據庫不理解對象。相反,關系數據庫會強行使用自己的類型系統和關系數據模型(表),每張表包含一組元組(行),每行包含具有固定數目的靜態類型字段(列)。如果應用程序的對象模型不能夠方便地轉換到關系模型,那么在將對象映射到元組以及將元組映射回對象方面,會碰到一定難度。這種困難常被稱為阻礙性不匹配(impedence-mismatch)問題。 對象持久性 如果希望透明地存儲 Python 對象,而不丟失其身份和類型等信息,則需要某種形式的對象序列化:它是一個將任意復雜的對象轉成對象的文本或二進制表示的過程。同樣,必須能夠將對象經過序列化后的形式恢復到原有的對象。在 Python 中,這種序列化過程稱為 pickle,可以將對象 pickle 成字符串、磁盤上的文件或者任何類似于文件的對象,也可以將這些字符串、文件或任何類似于文件的對象 unpickle 成原來的對象。我們將在本文后面詳細討論 pickle。 假定您喜歡將任何事物都保存成對象,而且希望避免將對象轉換成某種基于非對象存儲的開銷;那么 pickle 文件可以提供這些好處,但有時可能需要比這種簡單的 pickle 文件更健壯以及更具有可伸縮性的事物。例如,只用 pickle 不能解決命名和查找 pickle 文件這樣的問題,另外,它也不能支持并發地訪問持久性對象。如果需要這些方面的功能,則要求助類似于 ZODB(針對 Python 的 Z 對象數據庫)這類數據庫。ZODB 是一個健壯的、多用戶的和面向對象的數據庫系統,它能夠存儲和管理任意復雜的 Python 對象,并支持事務操作和并發控制。(請參閱 參考資料,以下載 ZODB。)令人足夠感興趣的是,甚至 ZODB 也依靠 Python 的本機序列化能力,而且要有效地使用 ZODB,必須充分了解 pickle。 另一種令人感興趣的解決持久性問題的方法是 Prevayler,它最初是用 Java 實現的(有關 Prevaylor 方面的developerWorks 文章,請參閱 參考資料)。最近,一群 Python 程序員將 Prevayler 移植到了 Python 上,另起名為 PyPerSyst,由 SourceForge 托管(有關至 PyPerSyst 項目的鏈接,請參閱 參考資料)。Prevayler/PyPerSyst 概念也是建立在 Java 和 Python 語言的本機序列化能力之上。PyPerSyst 將整個對象系統保存在內存中,并通過不時地將系統快照 pickle 到磁盤以及維護一個命令日志(通過此日志可以重新應用最新的快照)來提供災難恢復。所以,盡管使用 PyPerSyst 的應用程序受到可用內存的限制,但好處是本機對象系統可以完全裝入到內存中,因而速度極快,而且實現起來要比如 ZODB 這樣的數據庫簡單,ZODB 允許對象的數目比同時在能內存中所保持的對象要多。 既然我們已經簡要討論了存儲持久對象的各種方法,那么現在該詳細探討 pickle 過程了。雖然我們主要感興趣的是探索以各種方式來保存 Python 對象,而不必將其轉換成某種其它格式,但我們仍然還有一些需要關注的地方,譬如:如何有效地 pickle 和 unpickle 簡單對象以及復雜對象,包括定制類的實例;如何維護對象的引用,包括循環引用和遞歸引用;以及如何處理類定義發生的變化,從而使用以前經過 pickle 的實例時不會發生問題。我們將在隨后關于 Python 的 pickle 能力探討中涉及所有這些問題。 一些經過 pickle 的 Python pickle 模塊及其同類模塊 cPickle 向 Python 提供了 pickle 支持。后者是用 C 編碼的,它具有更好的性能,對于大多數應用程序,推薦使用該模塊。我們將繼續討論 pickle ,但本文的示例實際是利用了 cPickle 。由于其中大多數示例要用 Python shell 來顯示,所以先展示一下如何導入 cPickle ,并可以作為 pickle 來引用它: >>> import cPickle as pickle 現在已經導入了該模塊,接下來讓我們看一下 pickle 接口。 pickle 模塊提供了以下函數對: dumps(object) 返回一個字符串,它包含一個 pickle 格式的對象; loads(string) 返回包含在 pickle 字符串中的對象; dump(object, file) 將對象寫到文件,這個文件可以是實際的物理文件,但也可以是任何類似于文件的對象,這個對象具有 write() 方法,可以接受單個的字符串參數; load(file) 返回包含在 pickle 文件中的對象。 缺省情況下, dumps() 和 dump() 使用可打印的 ASCII 表示來創建 pickle。兩者都有一個 final 參數(可選),如果為 True ,則該參數指定用更快以及更小的二進制表示來創建 pickle。 loads() 和 load() 函數自動檢測 pickle 是二進制格式還是文本格式。 清單 1 顯示了一個交互式會話,這里使用了剛才所描述的 dumps() 和 loads() 函數: 清單 1. dumps() 和 loads() 的演示- >>>?t1??
- ('this?is?a?string',?42,?[1,?2,?3],?None)??
- >>>?p1?=?pickle.dumps(t1)??
- >>>?p1??
- "(S'this?is?a?string'/nI42/n(lp1/nI1/naI2/naI3/naNtp2/n."??
- >>>?print?p1??
- (S'this?is?a?string'??
- I42??
- (lp1??
- I1??
- aI2??
- aI3??
- aNtp2??
- .??
- >>>?t2?=?pickle.loads(p1)??
- >>>?t2??
- ('this?is?a?string',?42,?[1,?2,?3],?None)??
- >>>?p2?=?pickle.dumps(t1,?True)??
- >>>?p2??
- '(U/x10this?is?a?stringK*]q/x01(K/x01K/x02K/x03eNtq/x02.'??
- >>>?t3?=?pickle.loads(p2)??
- >>>?t3??
- ('this?is?a?string',?42,?[1,?2,?3],?None)??
原文地址:?點擊打開鏈接
19.4. Pickled Objects?
19.4. Pickle對象?
?
Probably the biggest limitation of DBM keyed files is in what they can store: data stored under a key must be a simple text string. If you want to store Python objects in a DBM file, you can sometimes manually convert them to and from strings on writes and reads (e.g., with str and eval calls), but this takes you only so far. For arbitrarily complex Python objects such as class instances and nested data structures, you need something more. Class instance objects, for example, cannot be later re-created from their standard string representations. Custom to-string conversions are error prone and not general.?
?
DBM 鍵控文件(DBM keyed file)最大的限制也許在于他們可以存儲的東西:一個鍵值下存儲的數據必須是個簡單文本字符串。如果您想要在DBM文件中儲存Python對象,有時您 可以在讀寫的時候,手動進行與字符串的轉換(例如,用str和eval調用),但只能做到這樣。對任意復雜的Python對象,如類實例和嵌套的數據結 構,您需要更多的東西。例如,類實例對象以后無法從其標準字符串表達(string representation)重建。自定義的到字符串的轉換容易出錯,并且不通用。?
?
The Python pickle module, a standard part of the Python system, provides the conversion step needed. It converts nearly arbitrary Python in-memory objects to and from a single linear string format, suitable for storing in flat files, shipping across network sockets between trusted sources, and so on. This conversion from object to string is often called serializationarbitrary data structures in memory are mapped to a serial string form.?
?
Python 系統的標準部件,pickle模塊,提供了所需的轉換步驟。它可以將幾乎任意的Python內存對象,轉換為單一線性的字符串格式,使之適于無格式文件存 儲,或在可靠來源之間跨越網絡套接口傳輸等等,并可反向轉換。這種從對象到字符串的轉換通常被稱為序列化(serialization):將內存中的任意 數據結構映射為串行字符串形式。?
?
The string representation used for objects is also sometimes referred to as a byte stream, due to its linear format. It retains all the content and references structure of the original in-memory object. When the object is later re-created from its byte string, it will be a new in-memory object identical in structure and value to the original, though located at a different memory address. The re-created object is effectively a copy of the original.?
?
對象的字符串表達由于其線性的格式,有時也被稱為字節流。它包含了原始內存中對象的所有內容和引用結構。當對象后來從其字節串重建時,內存中新建的對象與原對象具有相同的結構和值,但位于不同的內存地址。該重建對象實際上是原對象的復制。?
?
Pickling works on almost any Python datatypenumbers, lists, dictionaries, class instances, nested structures, and moreand so is a general way to store data. Because pickles contain native Python objects, there is almost no database API to be found; the objects stored are processed with normal Python syntax when they are later retrieved.?
?
Pickle可用于幾乎所有的Python數據類型:數字、列表、字典、類實例、嵌套結構,等等,因此它是存儲數據的通用方法。因為pickle包含的是Python本地對象,所以幾乎沒有數據庫的API;對象存儲與處理及后來的提取用的都是通常的Python語法。?
?
19.4.1. Using Object Pickling?
?
19.4.1. 使用對象pickle?
?
Pickling may sound complicated the first time you encounter it, but the good news is that Python hides all the complexity of object-to-string conversion. In fact, the pickle module 's interfaces are incredibly simple to use. For example, to pickle an object into a serialized string, we can either make a pickler and call its methods or use convenience functions in the module to achieve the same effect:?
?
第 一次聽到pickle,可能覺得有點復雜,但好消息是,Python隱藏了所有從對象到字符串轉換的復雜性。事實上,pickle模塊的接口簡單易用,簡 直令人難以置信。例如,要pickle對象到一個序列化字符串,我們可以生成一個pickler,并調用其方法,或使用模塊中的便捷函數來達到相同的效 果:?
?
Make a new pickler for pickling to an open output file object file.?
生成一個新的pickler,用來pickle到一個打開的輸出文件對象file。?
?
Write an object onto the pickler's file/stream.?
寫一個對象到pickler的文件/流。?
?
Same as the last two calls combined: pickle an object onto an open file.?
等同于上兩個調用的組合:pickle對象到一個打開的文件。?
?
Return the pickled representation of object as a character string.?
返回一個字符串作為已pickle對象的表達。?
?
Unpickling from a serialized string back to the original object is similarboth object and convenience function interfaces are available:?
?
從一個序列化字符串unpickle回原始對象是類似的,可以用對象也可以用便捷函數接口:?
?
Make an unpickler for unpickling from an open input file object file.?
生成一個unpickler,用來從一個打開的文件對象file unpickle。?
?
Read an object from the unpickler's file/stream.?
從unpickler的文件/流讀取一個對象。?
?
Same as the last two calls combined: unpickle an object from an open file.?
等同于上兩個調用的組合:從一個打開的文件unpickle一個對象。?
?
Read an object from a character string rather than a file.?
從字符串讀取一個對象,而不是從文件。?
?
Pickler and Unpickler are exported classes. In all of the preceding cases, file is either an open file object or any object that implements the same attributes as file objects:?
?
Pickler和Unpickler是導出類。在上述所有情況下,file是個已打開的文件對象,或者是實現了以下文件對象屬性的任何對象:?
?
Pickler calls the file's write method with a string argument.?
?
Pickler會調用文件的write方法,參數是個字符串。?
?
Unpickler calls the file's read method with a byte count, and readline without arguments.?
?
Unpickler會調用文件的read方法,參數是字節數,以及readline,無參數。?
?
Any object that provides these attributes can be passed in to the file parameters. In particular, file can be an instance of a Python class that provides the read/write methods (i.e., the expected file-like interface). This lets you map pickled streams to in-memory objects with classes, for arbitrary use. For instance, the StringIO standard library module discussed in Chapter 3 provides classes that map file calls to and from in-memory strings.?
?
任 何提供這些屬性的對象都可以作為file參數傳入。特別是,file可以是一個提供了讀/寫方法的Python類實例(即預期的類似文件的接口)。這讓您 可以用類映射pickle流到內存對象,并可任意使用。例如,第3章討論的標準庫模塊StringIO提供的類,它們可映射文件調用到內存字符串或反之。?
?
This hook also lets you ship Python objects across a network, by providing sockets wrapped to look like files in pickle calls at the sender, and unpickle calls at the receiver (see the sidebar "Making Sockets Look Like Files," in Chapter 13, for more details). In fact, for some, pickling Python objects across a trusted network serves as a simpler alternative to network transport protocols such as SOAP and XML-RPC; provided that Python is on both ends of the communication (pickled objects are represented with a Python-specific format, not with XML text).?
?
該 掛鉤也可以讓您通過網絡傳輸Python對象,只要封裝套接口,使之看上去像發送端pickle調用中的文件,以及像接收端unpickle調用中的文件 (詳見第13章側欄“使套接口看上去像文件”)。事實上,對一些人來說,pickle Python對象并在一個值得信賴的網絡上傳輸,是替代如SOAP和XML-RPC之類網絡傳輸協議的一個簡單方法;只要通信的兩端都有Python(被 pickle的對象是用Python專有的格式表達的,而不是用XML文本)。?
?
19.4.2. Picking in Action?
?
19.4.2. Pickle實戰?
?
In more typical use, to pickle an object to a flat file, we just open the file in write mode and call the dump function:?
?
典型的使用情況是,pickle對象到無格式文件,我們只需以寫模式打開文件,并調用dump函數:?
?
?
Notice the nesting in the object pickled herethe pickler handles arbitrary structures. To unpickle later in another session or program run, simply reopen the file and call load:?
?
注意這個被pickle對象中的嵌套:pickler可以處理任意結構。然后,在另一個會話或程序中unpickle,只要重新打開該文件,并調用load:?
?
?
The object you get back from unpickling has the same value and reference structure as the original, but it is located at a different address in memory. This is true whether the object is unpickled in the same or a future process. In Python-speak, the unpickled object is == but is not is:?
?
unpickle所得的對象具有與原對象相同的值和引用結構,但它位于不同的內存地址。無論在同一進程或另一進程unpickle,都是這樣。用Python的話來說,unpickle后的對象是“==”關系,但不是“is”關系:?
?
?
To make this process simpler still, the module in Example 19-1 wraps pickling and unpickling calls in functions that also open the files where the serialized form of the object is stored.?
?
為了讓這一過程更簡單,例19-1中的模塊把pickle和unpickle調用封裝在函數中,在函數中同時還打開文件,并將對象的序列化存儲在該文件中。?
?
Example 19-1. PP3E\Dbase\filepickle.py
切換行號顯示
1 import pickle2 3 def saveDbase(filename, object):4 file = open(filename, 'w')5 pickle.dump(object, file) # pickle to file6 file.close( ) # any file-like object will do7 8 def loadDbase(filename):9 file = open(filename, 'r')10 object = pickle.load(file) # unpickle from file11 file.close( ) # re-creates object in memory12 return object
?
To store and fetch now, simply call these module functions; here they are in action managing a fairly complex structure with multiple references to the same nested objectthe nested list called L at first is stored only once in the file:?
?
現在,存儲和提取時只需調用這些模塊函數;以下實例是個相當復雜的結構,具有對同一嵌套對象的多重引用,該嵌套列表,即第1個L,在文件中只會保存一次:?
?
?
Besides built-in types like the lists, tuples, and dictionaries of the examples so far, class instances may also be pickled to file-like objects. This provides a natural way to associate behavior with stored data (class methods process instance attributes) and provides a simple migration path (class changes made in module files are automatically picked up by stored instances). Here's a brief interactive demonstration:?
?
除 了內置的類型,如以上例子中的列表,元組和字典,類實例也可被pickle到類似文件的對象中。這提供了一個自然的方式來關聯行為與存儲的數據(類方法處 理實例的屬性),并提供了一條簡單的遷移路徑(被存儲的實例將自動獲得模塊文件中對類的更改)。以下是個簡短的交互演示:?
?
?
We'll explore how this works in more detail in conjunction with shelves later in this chapteras we'll see, although the pickle module can be used directly, it is also the underlying translation engine in both shelves and ZODB databases.?
?
我們將與本章下面的shelve一起詳細探討這是如此工作的。我們將會看到,雖然pickle模塊可直接使用,但它也是shelve和ZODB數據庫的底層翻譯引擎。?
?
In fact, Python can pickle just about anything, except for:?
?
事實上,Python可以pickle任何東西,除了:?
?
Compiled code objects; functions and classes record just their names in pickles, to allow for later reimport and automatic acquisition of changes made in module files.?
?
編譯的代碼對象;函數和類在pickle中只是記錄了它們的名字,以便后來重新導入和自動獲取模塊文件中的更改。?
?
Instances of classes that do not follow class importability rules (more on this at the end of the section "Shelve Files," later in this chapter).?
?
不遵守類可導入規則(class importability rule)的類實例(本章后面“Shelve文件”一節的尾部有更多相關內容)。?
?
Instances of some built-in and user-defined types that are coded in C or depend upon transient operating system states (e.g., open file objects cannot be pickled).?
?
用C編碼的或依賴于操作系統瞬態的一些內置的和用戶定義類型的實例(例如,打開的文件對象無法pickle)。?
?
A?PicklingError?is raised if an object cannot be pickled.?
?
如果對象不能pickle,會引發PickleError。?
?
19.4.3. Pickler Protocols and cPickle?
?
19.4.3. Pickler協議和cPickle?
?
In recent Python releases, the pickler introduced the notion of protocolsstorage formats for pickled data. Specify the desired protocol by passing an extra parameter to the pickling calls (but not to unpickling calls: the protocol is automatically determined from the pickled data):?
?
在最近的Python版本中,pickler推出了協議的概念:pickle數據的保存格式。通過pickle調用時傳入一個額外的參數,可指定所需的協議(但unpickle調用不需要:協議是自動從已pickle的數據確定的):?
?
?
Pickled data may be created in either text or binary protocols. By default, the storage protocol is text (also known as protocol 0). In text mode, the files used to store pickled objects may be opened in text mode as in the earlier examples, and the pickled data is printable ASCII text, which can be read (it's essentially instructions for a stack machine).?
?
Pickle 數據可以按文本協議或二進制協議產生。默認情況下,存儲協議是文本協議(也稱為0號協議)。在文本模式下,用來存儲pickle對象的文件可以用文本模式 打開,如上述的例子,并且pickle的數據是可打印的ASCII文本,并且是可讀的(這基本上是對堆棧機實現的指示)。?
?
The alternative protocols (protocols 1 and 2) store the pickled data in binary format and require that files be opened in binary mode (e.g., rb, wb). Protocol 1 is the original binary format; protocol 2, added in Python 2.3, has improved support for pickling of new-style classes. Binary format is slightly more efficient, but it cannot be inspected. An older option to pickling calls, the bin argument, has been subsumed by using a pickling protocol higher than 0. The pickle module also provides a HIGHEST_PROTOCOL variable that can be passed in to automatically select the maximum value.?
?
其 他協議(1號和2號協議 )以二進制格式存儲pickle數據,并要求文件以二進制模式打開(例如:rb、wb)。1號協議是原始二進制格式;2號協議是Python 2.3增加的,它改善了對新型類pickle的支持。二進制格式效率更高一點,但它無法進行查看。舊的pickle調用有一個選項,即bin參數,現已被 歸入使用大于0的協議。pickle模塊還提供了一個HIGHEST_PROTOCOL變量,傳入它可以自動選擇最大的協議值。?
?
One note: if you use the default text protocol, make sure you open pickle files in text mode later. On some platforms, opening text data in binary mode may cause unpickling errors due to line-end formats on Windows:?
?
注意:如果您使用默認的文本協議,以后請務必以文本模式打開pickle文件。在一些平臺上,因為Windows的行尾格式不同,以二進制模式打開文本數據可能會導致unpickle錯誤:?
?
?
One way to sidestep this potential issue is to always use binary mode for your files, even for the text pickle protocol. Since you must open files in binary mode for the binary pickler protocols anyhow (higher than the default 0), this isn't a bad habit to get into:?
?
回避這個潛在問題的方法之一是,總是使用二進制模式的文件,即使是用文本pickle協議。至少對于二進制pickler協議(高于默認0),您必須以二進制模式打開文件,所以這不是一個壞習慣:?
?
?
Refer to Python's library manual for more information on the pickler. Also check out marshal, a module that serializes an object too, but can handle only simple object types. pickle is more general than marshal and is normally preferred.?
?
請參考Python庫手冊,以了解更多pickler的信息。另外,請查閱marshal,它也是一個序列化對象的模塊,但只能處理簡單對象類型。pickle比marshal更通用,并通常是首選。?
?
And while you are flipping (or clicking) through that manual, be sure to also see the entries for the cPickle modulea reimplementation of pickle coded in C for faster performance. You can explicitly import cPickle for a substantial speed boost; its chief limitation is that you cannot subclass its versions of Pickle and Unpickle because they are functions, not classes (this is not required by most programs). The pickle and cPickle modules use compatible data formats, so they may be used interchangeably.?
?
而 當你翻看(或點擊)Python手冊時,請一定也要看看cPickle模塊的條目,它是pickle的C語言實現,性能上更快。您可以顯式導入 cPickle替代pickle,以大幅提升速度;其主要的限制是,你不能繼承該版本的Pickle和Unpickle,因為它們是函數,而不是類(多數 程序并不要求它們是類)。pickle和cPickle模塊使用兼容的數據格式,所以它們可以互換使用。?
總結
以上是生活随笔為你收集整理的Python pickle模块学习(超级详细)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机电路电子技术试题答案,数字电子技术
- 下一篇: 手机中的传感器及其应用场景