pickle, cPickle 模块:序列化 Python 对象
pickle
模块实现了一种算法,可以将任意一个 Python
对象转化为一系列的字节,也可以将这些字节重构为一个有相同特征的新对象。
由于字节可以被传输或者存储,因此 pickle
事实上实现了传递或者保存 Python
对象的功能。
cPickle
使用 C
而不是 Python
实现了相同的算法,因此速度上要比 pickle
快一些。但是它不允许用户从 pickle
派生子类。如果子类对你的使用来说无关紧要,那么 cPickle
是个更好的选择。
In [1]:
- try:
- import cPickle as pickle
- except:
- import pickle
编码和解码
使用 pickle.dumps()
可以将一个对象转换为字符串(dump string
):
In [2]:
- data = [ { 'a':'A', 'b':2, 'c':3.0 } ]
- data_string = pickle.dumps(data)
- print "DATA:"
- print data
- print "PICKLE:"
- print data_string
- DATA:
- [{'a': 'A', 'c': 3.0, 'b': 2}]
- PICKLE:
- (lp1
- (dp2
- S'a'
- S'A'
- sS'c'
- F3
- sS'b'
- I2
- sa.
虽然 pickle
编码的字符串并不一定可读,但是我们可以用 pickle.loads()
来从这个字符串中恢复原对象中的内容(load string
):
In [3]:
- data_from_string = pickle.loads(data_string)
- print data_from_string
- [{'a': 'A', 'c': 3.0, 'b': 2}]
编码协议
dumps
可以接受一个可省略的 protocol
参数(默认为 0),目前有 3 种编码方式:
- 0:原始的
ASCII
编码格式 - 1:二进制编码格式
- 2:更有效的二进制编码格式
当前最高级的编码可以通过
HIGHEST_PROTOCOL
查看:
In [4]:
- print pickle.HIGHEST_PROTOCOL
- 2
例如:
In [5]:
- data_string_1 = pickle.dumps(data, 1)
- print "Pickle 1:", data_string_1
- data_string_2 = pickle.dumps(data, 2)
- print "Pickle 2:", data_string_2
- Pickle 1: ]q}q(UaUAU[email protected]UbKua.
- Pickle 2: �]q}q(UaUAU[email protected]UbKua.
如果 protocol
参数指定为负数,那么将调用当前的最高级的编码协议进行编码:
In [6]:
- print pickle.dumps(data, -1)
- �]q}q(UaUAU[email protected]UbKua.
从这些格式中恢复对象时,不需要指定所用的协议,pickle.load()
会自动识别:
In [7]:
- print "Load 1:", pickle.loads(data_string_1)
- print "Load 2:", pickle.loads(data_string_2)
- Load 1: [{'a': 'A', 'c': 3.0, 'b': 2}]
- Load 2: [{'a': 'A', 'c': 3.0, 'b': 2}]
存储和读取 pickle 文件
除了将对象转换为字符串这种方式,pickle
还支持将对象写入一个文件中,通常我们将这个文件命名为 xxx.pkl
,以表示它是一个 pickle
文件:
存储和读取的函数分别为:
pickle.dump(obj, file, protocol=0)
将对象序列化并存入file
文件中pickle.load(file)
从file
文件中的内容恢复对象
将对象存入文件:
In [8]:
- with open("data.pkl", "wb") as f:
- pickle.dump(data, f)
从文件中读取:
In [9]:
- with open("data.pkl") as f:
- data_from_file = pickle.load(f)
- print data_from_file
- [{'a': 'A', 'c': 3.0, 'b': 2}]
清理生成的文件:
In [10]:
- import os
- os.remove("data.pkl")