摘要:使用來(lái)創(chuàng)建一個(gè)表示該對(duì)象值的字符串。數(shù)據(jù)被序列化以后,你可以將它們寫(xiě)入文件套接字管道等等中。如果你使用管道或者套接字,在通過(guò)連至另一端的連接傾倒所有對(duì)象推送數(shù)據(jù)之后,別忘了沖洗。
目的:Python對(duì)象序列化
可用性:pickle至少1.4版本,cPickle 1.5版本以上
pickle模塊實(shí)現(xiàn)了一種算法,將任意一個(gè)Python對(duì)象轉(zhuǎn)化成一系列字節(jié)(byets)。此過(guò)程也調(diào)用了serializing對(duì)象。代表對(duì)象的字節(jié)流之后可以被傳輸或存儲(chǔ),再重構(gòu)后創(chuàng)建一個(gè)擁有相同特征(the same characteristics)的新的對(duì)象。
cPickle使用C而不是Python,實(shí)現(xiàn)了相同的算法。這比Python實(shí)現(xiàn)要快好幾倍,但是它不允許用戶從Pickle派生子類。如果子類對(duì)你的使用來(lái)說(shuō)無(wú)關(guān)緊要,那么cPickle是個(gè)更好的選擇。
警告:本文檔直接說(shuō)明,pickle不提供安全保證。如果你在多線程通信(inter-process communication)或者數(shù)據(jù)存儲(chǔ)或存儲(chǔ)數(shù)據(jù)中使用pickle,一定要小心。請(qǐng)勿信任你不能確定為安全的數(shù)據(jù)。
導(dǎo)入如平常一樣,嘗試導(dǎo)入cPickle,給它賦予一個(gè)別名“pickle”。如果因?yàn)槟承┰驅(qū)胧?,退而求其次到Python的原生(native)實(shí)現(xiàn)pickle模塊。如果cPickle可用,能給你提供一個(gè)更快速的執(zhí)行,否則只能是輕便的執(zhí)行(the portable implementation)。
pythontry: import cPickle as pickle except: import pickle編碼和解碼
第一個(gè)例子將一種數(shù)據(jù)結(jié)構(gòu)編碼成一個(gè)字符串,然后把該字符串打印至控制臺(tái)。使用一種包含所有原生類型(native types)的數(shù)據(jù)結(jié)構(gòu)。任何類型的實(shí)例都可被腌漬(pickled,譯者注:模塊名稱pickle的中文含義為腌菜),在稍后的例子中會(huì)演示。使用pickle.dumps()來(lái)創(chuàng)建一個(gè)表示該對(duì)象值的字符串。
pythontry: import cPickle as pickle except: import pickle import pprint data = [ { "a":"A", "b":2, "c":3.0 } ] print "DATA:", pprint.pprint(data) data_string = pickle.dumps(data) print "PICKLE:", data_string
pickle默認(rèn)僅由ASCII字符組成。也可以使用更高效的二進(jìn)制格式(binary format),只是因?yàn)樵诖蛴〉臅r(shí)候更易于理解,本頁(yè)的所有例子都使用ASCII輸出。
python$ python pickle_string.py DATA:[{"a": "A", "b": 2, "c": 3.0}] PICKLE: (lp1 (dp2 S"a" S"A" sS"c" F3 sS"b" I2 sa.
數(shù)據(jù)被序列化以后,你可以將它們寫(xiě)入文件、套接字、管道等等中。之后你也可以從文件中讀取出來(lái)、將它反腌漬(unpickled)而構(gòu)造一個(gè)具有相同值得新對(duì)象。
pythontry: import cPickle as pickle except: import pickle import pprint data1 = [ { "a":"A", "b":2, "c":3.0 } ] print "BEFORE:", pprint.pprint(data1) data1_string = pickle.dumps(data1) data2 = pickle.loads(data1_string) print "AFTER:", pprint.pprint(data2) print "SAME?:", (data1 is data2) print "EQUAL?:", (data1 == data2)
如你所見(jiàn),這個(gè)新構(gòu)造的對(duì)象與原對(duì)象相同,但并非同一對(duì)象。這不足為奇。
python$ python pickle_unpickle.py BEFORE:[{"a": "A", "b": 2, "c": 3.0}] AFTER:[{"a": "A", "b": 2, "c": 3.0}] SAME?: False EQUAL?: True與流一起工作
除dumps()和loads()外,pickle還提供一對(duì)用在類文件流(file-like streams)的轉(zhuǎn)化函數(shù)??梢酝粋€(gè)流中寫(xiě)對(duì)個(gè)對(duì)象,然后從流中把它們讀取出來(lái),此過(guò)程不需要預(yù)先寫(xiě)入的對(duì)象有幾個(gè)、它們多大。
pythontry: import cPickle as pickle except: import pickle import pprint from StringIO import StringIO class SimpleObject(object): def __init__(self, name): self.name = name l = list(name) l.reverse() self.name_backwards = "".join(l) return data = [] data.append(SimpleObject("pickle")) data.append(SimpleObject("cPickle")) data.append(SimpleObject("last")) # 使用StringIO模擬一個(gè)文件 out_s = StringIO() # 寫(xiě)入該流 for o in data: print "WRITING: %s (%s)" % (o.name, o.name_backwards) pickle.dump(o, out_s) out_s.flush() # 建立一個(gè)可讀流 in_s = StringIO(out_s.getvalue()) # 讀數(shù)據(jù) while True: try: o = pickle.load(in_s) except EOFError: break else: print "READ: %s (%s)" % (o.name, o.name_backwards)
這個(gè)例子使用SringIO緩存器(buffer)模擬流,所以在建立可讀流的時(shí)候我們玩了一把。一個(gè)簡(jiǎn)單數(shù)據(jù)庫(kù)的格式化也可以使用pickles來(lái)存儲(chǔ)對(duì)象,只是shelve與之工作更加簡(jiǎn)便。
python$ python pickle_stream.py WRITING: pickle (elkcip) WRITING: cPickle (elkciPc) WRITING: last (tsal) READ: pickle (elkcip) READ: cPickle (elkciPc) READ: last (tsal)
除了存儲(chǔ)數(shù)據(jù),pickles在進(jìn)程間通信(inter-process communication)中也非常稱手。例如,使用os.fork()和os.pipe()可以創(chuàng)立工作者進(jìn)程(worker processes),從一個(gè)管道(pipe)讀取作業(yè)指令(job instruction)然后將結(jié)果寫(xiě)入另一個(gè)管道。管理工作者池(worker pool)和將作業(yè)送入、接受響應(yīng)(response)的核心代碼可被重用,因?yàn)樽鳂I(yè)和響應(yīng)并不屬于某個(gè)特定類中。如果你使用管道或者套接字(sockets),在通過(guò)連至另一端(end)的連接傾倒(dumps)所有對(duì)象、推送數(shù)據(jù)之后,別忘了沖洗(flush)。如果你想寫(xiě)自己的工作者池管理器,請(qǐng)看multiprocessing。
原文:pickle and cPickle – Python object serialization - Python Module of the Week 的前半部分
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/45327.html
摘要:對(duì)象序列化從這篇文章粗略翻譯的模塊可以實(shí)現(xiàn)任意的對(duì)象轉(zhuǎn)換為一系列字節(jié)即序列化對(duì)象的算法。的文檔明確的表明它不提供安全保證。而利用則可以控制序列化的細(xì)節(jié)。 Python 對(duì)象序列化——pickle and cPickle 從這篇文章粗略翻譯的pickle and cPickle pickle模塊可以實(shí)現(xiàn)任意的Python對(duì)象轉(zhuǎn)換為一系列字節(jié)(即序列化對(duì)象)的算法。這些字節(jié)流可以 被...
摘要:重構(gòu)對(duì)象的問(wèn)題當(dāng)與你自己的類一起工作時(shí),你必須保證類被腌漬出現(xiàn)在讀取的進(jìn)程的命名空間中。因?yàn)槭褂弥刀荒鼙浑鐫n的類,可以定義和來(lái)返回狀態(tài)的一個(gè)子集,才能被腌漬。腌漬和反腌漬該圖來(lái)創(chuàng)建一個(gè)結(jié)點(diǎn)集合。 承接上文 pickle和cPickle:Python對(duì)象的序列化(上) 。 重構(gòu)對(duì)象的問(wèn)題 當(dāng)與你自己的類一起工作時(shí),你必須保證類被腌漬出現(xiàn)在讀取pickle的進(jìn)程的命名空間中。...
摘要:利用標(biāo)準(zhǔn)庫(kù)中的的模塊可以將對(duì)象轉(zhuǎn)換為一種可以傳輸或存儲(chǔ)的格式。主要方法模塊中有兩個(gè)主要函數(shù),它們是和。具體語(yǔ)法為返回一個(gè)字符串,而不是存入文件中。該方法用于反序列化,即將序列化的對(duì)象重新恢復(fù)成對(duì)象。除此之外,這兩個(gè)模塊的接口是幾乎完全相同。 對(duì)象存在于程序運(yùn)行時(shí)的內(nèi)存中,當(dāng)程序不再運(yùn)行時(shí)或斷電關(guān)機(jī)時(shí),這些對(duì)象便不再存在。我現(xiàn)在想把對(duì)象保存下來(lái),方便以后使用,這就是持久化技術(shù)。利用 py...
摘要:反序列化安全問(wèn)題一這一段時(shí)間使用做開(kāi)發(fā),使用了存儲(chǔ),閱讀了源碼,發(fā)現(xiàn)在存儲(chǔ)到過(guò)程中,利用了模塊進(jìn)行序列化以及反序列化正好根據(jù)該樣例學(xué)習(xí)一波反序列化相關(guān)的安全問(wèn)題,不足之處請(qǐng)各位表哥指出。 Python 反序列化安全問(wèn)題(一) 這一段時(shí)間使用flask做web開(kāi)發(fā),使用了redis存儲(chǔ)session,閱讀了flask_session源碼,發(fā)現(xiàn)在存儲(chǔ)session到redis過(guò)程中,利用了...
摘要:默認(rèn)為或者說(shuō),是以格式保存對(duì)象如果設(shè)置為或者,則以壓縮的二進(jìn)制格式保存對(duì)象。但是,要小心坑試圖增加一個(gè)坑就在這里當(dāng)試圖修改一個(gè)已有鍵的值時(shí)沒(méi)有報(bào)錯(cuò),但是并沒(méi)有修改成功。要填平這個(gè)坑,需要這樣做多一個(gè)參數(shù)沒(méi)有坑了還用循環(huán)一下 pickle pickle是標(biāo)準(zhǔn)庫(kù)中的一個(gè)模塊,在Python 2中還有一個(gè)cpickle,兩者的區(qū)別就是后者更快。所以,下面操作中,不管是用import pick...
閱讀 2172·2023-04-25 20:45
閱讀 1085·2021-09-22 15:13
閱讀 3653·2021-09-04 16:48
閱讀 2589·2019-08-30 15:53
閱讀 940·2019-08-30 15:44
閱讀 957·2019-08-30 15:43
閱讀 1014·2019-08-29 16:33
閱讀 3443·2019-08-29 13:08