一、pickle
pickle模塊用來實現python對象的序列化和反序列化。通常地pickle將python對象序列化為二進制流或文件。
?
python對象與文件之間的序列化和反序列化:
pickle.dump()
pickle.load()
如果要實現python對象和字符串間的序列化和反序列化,則使用:
pickle.dumps()
pickle.loads()
?
可以被序列化的類型有:
* None,True 和 False;
* 整數,浮點數,復數;
* 字符串,字節流,字節數組;
* 包含可pickle對象的tuples,lists,sets和dictionaries;
* 定義在module頂層的函數:
* 定義在module頂層的內置函數;
* 定義在module頂層的類;
* 擁有__dict__()或__setstate__()的自定義類型;
?
注意:對于函數或類的序列化是以名字來識別的,所以需要import相應的module。
二、pickle的運行過程
在大部分情況下,要是的對象picklable,我們不需要額外的代碼。默認地pickle將智能地檢查類和實例的屬性,當一個類實例反序列化的時候,它的__init__()方法通常不被調用。而是首先創建一個未初始化的實例,然后再回復存儲的屬性。
?
但是可以通過實現下列的方法來修改默認的行為:
object.__getstate__() :默認地序列化對象的__dict__,但是如果你實現了__getstate__(),則__getstate__()函數返回的值將被序列化。
object.__setstate__(state) :如果類型實現了此方法,則在反序列化的時候,此方法用來恢復對象的屬性。
object.__getnewargs__() : 如果實例構造的時候(__new__())需要參數,則需要實現此函數。
注意:如果__getstate__()返回False,則在反序列化的時候__setstate__()則不被調用。
有的時候為了效率,或上面的3個函數不能滿足需求時,需要實現__reduce__()函數。
三、實例
import pickle
# An arbitrary collection of objects supported by pickle.
data = {
??? 'a': [1, 2.0, 3, 4+6j],
??? 'b': ("character string", b"byte string"),
??? 'c': set([None, True, False])
}
with open('data.pickle', 'wb') as f:
??? # Pickle the 'data' dictionary using the highest protocol available.
??? pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
???
with open('data.pickle', 'rb') as f:
??? # The protocol version used is detected automatically, so we do not
??? # have to specify it.
??? data = pickle.load(f)
??? print(str(data))
四、修改picklable類型的默認行為??
class TextReader:
??? """Print and number lines in a text file."""
??? def __init__(self, filename):
??????? self.filename = filename
??????? self.file = open(filename)
??????? self.lineno = 0
??? def readline(self):
??????? self.lineno += 1
??????? line = self.file.readline()
??????? if not line:
??????????? return None
??????? if line.endswith('\n'):
??????????? line = line[:-1]
??????? return "%i: %s" % (self.lineno, line)
??? def __getstate__(self):
??????? # Copy the object's state from self.__dict__ which contains
??????? # all our instance attributes. Always use the dict.copy()
??????? # method to avoid modifying the original state.
??????? state = self.__dict__.copy()
??????? # Remove the unpicklable entries.
??????? del state['file']
??????? return state
??? def __setstate__(self, state):
??????? # Restore instance attributes (i.e., filename and lineno).
??????? self.__dict__.update(state)
??????? # Restore the previously opened file's state. To do so, we need to
??????? # reopen it and read from it until the line count is restored.
??????? file = open(self.filename)
??????? for _ in range(self.lineno):
??????????? file.readline()
??????? # Finally, save the file.
??????? self.file = file
???????
reader = TextReader("hello.txt")
print(reader.readline())
print(reader.readline())
s = pickle.dumps(reader)
#print(s)
new_reader = pickle.loads(s)
print(new_reader.readline())
# the output is
# 1: hello
# 2: how are you
# 3: goodbye
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
