在「透過簡單範例來理解什麼是機器學習」這篇文章中提到了pickle函式庫的使用,本文來做進一步的闡述。
那麼為什麼需要序列化和反序列化這一操作呢?
方便儲存。序列化過程將文字訊息轉變為二進位資料流。這樣就資訊就容易儲存在硬碟之中,當需要讀取檔案的時候,從硬碟中讀取數據,然後再將其反序列化便可以得到原始的數據。在Python程式運行中得到了一些字串、列表、字典等數據,想要長久的保存下來,方便以後使用,而不是簡單的放入內存中關機斷電就丟失數據。 python模組大全中的Pickle模組就派上用場了,它可以將物件轉換為一種可以傳輸或儲存的格式。
loads()函數執行和load() 函數一樣的反序列化。取代接受一個流物件並去文件讀取序列化後的數據,它接受包含序列化後的數據的str對象, 直接返回的對象。
程式碼範例:
[python] view plain copy #!/usr/bin/env python # -*- coding: UTF-8 -*- import cPickle as pickle obj = 123, "abcdedf", ["ac", 123], {"key": "value", "key1": "value1"} print obj# 输出:(123, 'abcdedf', ['ac', 123], {'key1': 'value1', 'key': 'value'}) # 序列化到文件 with open(r"d:\a.txt", "r+") as f: pickle.dump(obj, f) with open(r"d:\a.txt") as f: print pickle.load(f)# 输出:(123, 'abcdedf', ['ac', 123], {'key1': 'value1', 'key': 'value'}) # 序列化到内存(字符串格式保存),然后对象可以以任何方式处理如通过网络传输 obj1 = pickle.dumps(obj) print type(obj1)# 输出:<type 'str'> print obj1# 输出:python专用的存储格式 obj2 = pickle.loads(obj1) print type(obj2)# 输出:<type 'tuple'> print obj2# 输出:(123, 'abcdedf', ['ac', 123], {'key1': 'value1', 'key': 'value'})
2.方便傳輸。當兩個進程在進行遠端通訊時,彼此可以發送各種類型的資料。無論是何種類型的數據,都會以二元序列的形式在網路上傳送。發送方需要把這個物件轉換為位元組序列,在能在網路上傳輸;接收方則需要把位元組序列在恢復為物件。
透過簡單範例來理解什麼是機器學習
#pickle是python語言的一個標準模組,安裝python後已包含pickle函式庫,不需要單獨再安裝。
pickle模組實現了基本的資料序列化和反序列化。透過pickle模組的序列化操作我們能夠將程式中運行的物件資訊保存到檔案中去,永久儲存;透過pickle模組的反序列化操作,我們能夠從檔案中建立上一次程式保存的物件。
在官方的介紹中,序列化操作的英文描述有好幾個單詞,如”serializing”, “pickling”, “serialization”, “marshalling” 或”flattening”等,它們都代表的是序列化的意思。對應的,反序列化操作的英文單字也有好多個,如”de-serializing”, “unpickling”, “deserailization”等。為了避免混淆,一般用”pickling”/“unpickling”, 或”serialization”/“deserailization”。 pickle
模組是以二進位的形式序列化後儲存到檔案中(儲存檔案的後綴為」.pkl”),無法直接開啟進行預覽。而python的另一個序列化標準模組json
,則是human-readable的,可以直接開啟檢視(例如在notepad++中查看)。
pickle模組有兩類主要的接口,即序列化和反序列化。
常採用這樣的方式使用:
[python] view plain copy import cPickle as pickle pickle.dump(obj,f) pickle.dumps(obj,f) pickle.load(f) pickle.loads(f)
其中序列化運算包含:
pickle.dump()
反序列化運算包含:
Pickler(file, protocol).dump(obj)
pickle.load()
Unpickler(file).load()
序列化的方法为 pickle.dump()
,该方法的相关参数如下:
pickle.dump(obj, file, protocol=None,*,fix_imports=True)
该方法实现的是将序列化后的对象obj以二进制形式写入文件file中,进行保存。它的功能等同于 Pickler(file, protocol).dump(obj)
。
关于参数file,有一点需要注意,必须是以二进制的形式进行操作(写入)。
参考前文的案例如下:
import picklewith open('svm_model_iris.pkl', 'wb') as f: pickle.dump(svm_classifier, f)
file为’svm_model_iris.pkl’,并且以二进制的形式(’wb’)写入。
关于参数protocol,一共有5中不同的类型,即(0,1,2,3,4)。(0,1,2)对应的是python早期的版本,(3,4)则是在python3之后的版本。
此外,参数可选 pickle.HIGHEST_PROTOCOL和pickle.DEFAULT_PROTOCOL。当前,python3.5版本中,pickle.HIGHEST_PROTOCOL的值为4,pickle.DEFAULT_PROTOCOL的值为3。当protocol参数为负数时,表示选择的参数是pickle.HIGHEST_PROTOCOL。
关于参数protocol,官方的详细介绍如下:
pickle.dumps()
方法的参数如下:
pickle.dumps(obj, protocol=None,*,fix_imports=True)pickle.dumps()
方法跟pickle.dump()
方法的区别在于,pickle.dumps()
方法不需要写入文件中,它是直接返回一个序列化的bytes对象。
pickle模块提供了序列化的面向对象的类方法,即 class pickle.Pickler(file, protocol=None,*,fix_imports=True)
,Pickler类有dump()方法。
Pickler(file, protocol).dump(obj) 实现的功能跟 pickle.dump() 是一样的。
关于Pickler类的其他method,请参考官方API。
插播一条硬广:技术文章转发太多,本文来自微信公众号:“Python数据之道”(ID:PyDataRoad)。
序列化的方法为 pickle.load()
,该方法的相关参数如下:
pickle.load(file, *,fix_imports=True, encoding=”ASCII”. errors=”strict”)
该方法实现的是将序列化的对象从文件file中读取出来。它的功能等同于 Unpickler(file).load()
。
关于参数file,有一点需要注意,必须是以二进制的形式进行操作(读取)。
参考前文的案例如下:
import picklewith open('svm_model_iris.pkl', 'rb') as f: model = pickle.load(f)
file为’svm_model_iris.pkl’,并且以二进制的形式(’rb’)读取。
读取的时候,参数protocol是自动选择的,load()方法中没有这个参数。
pickle.loads()
方法的参数如下:
pickle.loads(bytes_object, *,fix_imports=True, encoding=”ASCII”. errors=”strict”)pickle.loads()
方法跟pickle.load()
方法的区别在于,pickle.loads()
方法是直接从bytes对象中读取序列化的信息,而非从文件中读取。
pickle模块提供了反序列化的面向对象的类方法,即 class pickle.Unpickler(file, *,fix_imports=True, encoding="ASCII". errors="strict")
,Pickler类有load()方法。
Unpickler(file).load() 实现的功能跟 pickle.load() 是一样的。
关于Unpickler类的其他method,请参考官方API。
官方文档是这么介绍的,这里我就不进一步描述了。
pickle模块还是比较实用的,当然,关于pickle模块,其实还有许多的信息可以去了解,想了解更多信息的童鞋,建议可以阅读下python官方的API文档(library文件)。
以上是pickle庫的使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!