2011-09-21 68 views
34

我最近得到了一份任務,我需要在酸洗的表單中放置一個字典(其中每個鍵指的是一個列表)。唯一的問題是我不知道什麼醃漬的形式。任何人都可以指出我在一些優秀資源的正確方向上幫助我學習這個概念嗎?謝謝!在Python中瞭解酸洗

+34

http://docs.python.org/library/pickle.html是谷歌第一個針對「pickle」的搜索結果,甚至擊敗了保存的蔬菜的維基百科頁面。 – geoffspear

+17

@Wooble:我完全瞭解它的主題,但Google搜索因您的位置,搜索歷史記錄,甚至電子郵件/聊天記錄而異;)。但是,是的,+1指向文檔。 – 0xc0de

+6

@ 0xc0de對。對我來說,頂級參賽作品*是保存的蔬菜。 :-)猜猜我應該開始編碼更多。 –

回答

17

雖然其他人所指出的泡菜模塊上的Python文檔,這是一個很好的資源,你也可以檢查出Chapter 13: Serializing Python Objects潛入Python 3由馬克Pilgrim。

+0

感謝您指出解釋* why的資源*你會想醃一個python對象。 –

3

http://docs.python.org/library/pickle.html#example

import pickle 

data1 = {'a': [1, 2.0, 3, 4+6j], 
     'b': ('string', u'Unicode string'), 
     'c': None} 

selfref_list = [1, 2, 3] 
selfref_list.append(selfref_list) 

output = open('data.pkl', 'wb') 

# Pickle dictionary using protocol 0. 
pickle.dump(data1, output) 

# Pickle the list using the highest protocol available. 
pickle.dump(selfref_list, output, -1) 

output.close() 
66

鹹菜模塊實現了序列化和反序列化Python對象結構的根本,但強大的算法。

酸洗 -是過程,由此一個Python對象分層結構被轉換成字節流,並取儲存 -是逆操作,由此一個字節流被轉換回的對象分層結構。

酸洗(與在unpickle)被替代地稱爲系列化編組,或壓扁

import pickle 

data1 = {'a': [1, 2.0, 3, 4+6j], 
     'b': ('string', u'Unicode string'), 
     'c': None} 

selfref_list = [1, 2, 3] 
selfref_list.append(selfref_list) 

output = open('data.pkl', 'wb') 

# Pickle dictionary using protocol 0. 
pickle.dump(data1, output) 

# Pickle the list using the highest protocol available. 
pickle.dump(selfref_list, output, -1) 

output.close() 

要從醃製文件讀取 -

import pprint, pickle 

pkl_file = open('data.pkl', 'rb') 

data1 = pickle.load(pkl_file) 
pprint.pprint(data1) 

data2 = pickle.load(pkl_file) 
pprint.pprint(data2) 

pkl_file.close() 

源 - https://docs.python.org/2/library/pickle.html

+8

這只是我見過的最好的代碼示例之一。精美的格式和美妙的簡潔。謝謝。 – anon58192932

+1

我沒有得到爲什麼'data1 = pickle.load(pkl_file)'沒有加載完整文件(data.pkl)? – Naive

+0

酸洗需要文件輸出參數嗎?你如何保持序列化的對象在別處存儲它? – Praxiteles

3

Pickling in Python用於對Python對象進行序列化和反序列化,就像字典一樣。我通常使用cPickle模塊,因爲它可以比Pickle模塊快得多。

import cPickle as pickle  

def serializeObject(pythonObj): 
    return pickle.dumps(pythonObj, pickle.HIGHEST_PROTOCOL) 

def deSerializeObject(pickledObj): 
    return pickle.loads(pickledObj) 
19

酸洗是可以用來在相關國家從巨蟒對象轉換爲字符串,此字符串唯一地表示該對象的小型語言。然後,可以使用酸洗來將字符串轉換爲活動對象,方法是從創建該字符串的已保存狀態中「重建」對象。

>>> import pickle 
>>> 
>>> class Foo(object): 
... y = 1 
... def __init__(self, x): 
...  self.x = x 
...  return 
... def bar(self, y): 
...  return self.x + y 
... def baz(self, y): 
...  Foo.y = y 
...  return self.bar(y) 
... 
>>> f = Foo(2) 
>>> f.baz(3) 
5 
>>> f.y 
3 
>>> pickle.dumps(f) 
"ccopy_reg\n_reconstructor\np0\n(c__main__\nFoo\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'x'\np6\nI2\nsb." 

你可以在這裏看到的是,pickle不保存類的源代碼,但是存儲對類定義的引用。基本上,你幾乎可以讀取選擇的字符串......它說(粗略翻譯)「調用copy_reg的重建器,其中參數是__main__.Foo定義的類,然後做其他的東西」。其他的東西是實例的保存狀態。如果你看得更深,可以提取「字符串x」設置爲「整數2」(大致爲:S'x'\np6\nI2)。這實際上是字典條目的醃製字符串的剪輯部分... dictf.__dict__,它是{'x': 2}。如果你看看pickle的源代碼,它非常清楚地給出了從python到pickle字節碼的每種類型的對象和操作的翻譯。

還要注意酸洗語言有不同的變體。默認值是協議0,它更易讀。還有協議2,如下所示(1,3和4,取決於您使用的Python的版本)。

>>> pickle.dumps([1,2,3]) 
'(lp0\nI1\naI2\naI3\na.' 
>>> 
>>> pickle.dumps([1,2,3], -1) 
'\x80\x02]q\x00(K\x01K\x02K\x03e.' 

再次,它仍然是酸洗語的一種方言,你可以看到,該協議0字符串說「獲取列表,包括I1,I2,I3」,而方案2是難讀,但是說同樣的事情。第一位\x80\x02表明它是協議2 - 那麼你有]它說這是一個列表,然後你可以看到裏面的整數1,2,3。再次檢查pickle的源代碼以查看酸洗語言的確切映射。

要將酸洗反轉爲字符串,請使用加載/加載。

>>> p = pickle.dumps([1,2,3]) 
>>> pickle.loads(p) 
[1, 2, 3] 
+2

作爲一個初學者,我在腦海裏有這樣一個問題,醃菜在裏面做了什麼?這個答案比其他人更重要。 –

2

pickle模塊爲序列化和反序列化Python對象結構實現了一個基礎但強大的算法。 「Pickling」是將Python對象層次結構轉換爲字節流的過程,「unpickling」是相反的操作,即字節流轉換回對象層次結構。酸洗(或取消)也稱爲「序列化」,「編組」或「扁平化」,但爲了避免混淆,此處使用的術語是「酸洗」和「取消」。

泡菜模塊有一個稱爲cPickle模塊的優化堂兄。顧名思義,cPickle是用C編寫的,所以它比鹹菜快1000倍。但是,它不支持Pickler()和Unpickler()類的子類化,因爲在cPickle中這些是函數,而不是類。大多數應用程序不需要此功能,並且可以從cPickle的改進性能中受益。除此之外,兩個模塊的接口幾乎完全相同;本手冊介紹了通用接口,並在必要時指出了不同之處。在下面的討論中,我們使用術語「pickle」來共同描述pickle和cPickle模塊。

兩個模塊產生的數據流保證可以互換。

+0

務必始終以二進制模式打開使用協議> = 1創建的pickle文件。對於舊的基於ASCII的pickle協議0,只要保持一致,就可以使用文本模式或二進制模式。 在二進制模式下使用協議0編寫的pickle文件將包含單行換行符作爲行終止符,因此在記事本或其他不支持此格式的編輯器中查看時看起來會很「滑稽」。 – Naren

+1

cpickle被轉換爲Python中的_pickle 3 – Naren

+0

cpickle比pickle快得多,因爲顧名思義它是用c語言編寫的。 – Naren