Python3内置模块之Pickle和cPickle数据持久化方法小结

1,955 阅读2分钟

概述

模块Pickle实现了对一个 Python 对象结构的二进制的序列化和反序列化。  即当Python程序持续运行一些字符串、列表字典、甚至自定义的类等数据对象,需要持久化存储,即存储在磁盘中,防止运行在内存中,因断电等情况丢失数据。那么Pickle模块就派上用场了,它可以将对象转换为一种可以传输或存储的格式。python的pickle模块实现了基本的数据序列和反序列化。通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

与JSON模块的比较

可以看到pickle模块和看似相似,但其还是有着本质的不同,即:

  • JSON 是一个文本序列化格式(它输出 unicode 文本,尽管在大多数时候它会接着以 utf-8 编码),而 pickle 是一个二进制序列化格式;

  • JSON是字面量可读的,而pickle不是(可以类比base64的不可读性);

  • JSON是可互操作的,在Python系统之外广泛使用,而pickle则是Python专用的;

序列化与反序列化

通过二进制的方式读写目标存储文件,并利用dump序列化数据对象,load反序列化数据对象

D = {
    'name': 'bob',
    'major': {
        'english',
        'math'
    },
    'd': [1, 2, 3, 4, 5, 6, 7]
}

with open('D.pik', 'wb') as f:
    pickle.dump(D, f)

with open('D.pik', 'rb') as f:
    D = pickle.load(f)
    print(type(D))
    print(D)

示例结果:

<class 'dict'>
{'name': 'bob', 'major': {'english', 'math'}, 'd': [1, 2, 3, 4, 5, 6, 7]}

当然我们也可以序列化到内存(字符串格式保存),然后对象可以以任何方式处理如通过网络传输


pik = pickle.dumps(D)
print(pik)

D = pickle.loads(pik)
print(type(D))
print(D)

示例结果:

b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00bobq\x02X\x05\x00\x00\x00majorq\x03cbuiltins\nset\nq\x04]q\x05(X\x07\x00\x00\x00englishq\x06X\x04\x00\x00\x00mathq\x07e\x85q\x08Rq\tX\x01\x00\x00\x00dq\n]q\x0b(K\x01K\x02K\x03K\x04K\x05K\x06K\x07eu.'
<class 'dict'>
{'name': 'bob', 'major': {'english', 'math'}, 'd': [1, 2, 3, 4, 5, 6, 7]}

cPickle

cPickle包的功能和用法与pickle包几乎完全相同 (其存在差别的地方实际上很少用到),不同在于cPickle是基于c语言编写的,具有更好的性能,对于大多数应用程序,推荐使用该模块。对于上面的例子,如果想使用cPickle包,我们都可以将import语句改为import cPickle as pickle进行使用。