0%

pickel模块学习

Python-api pickle模块学习

前言

python3.9-doc-pickle:https://docs.python.org/3/library/pickle.html
在做实验时,可能需要将数据打包成pickle文件,方便后续的读取。pickle是一个python模块,源代码在Lib/pickle.py,可将python对象进行序列化和反序列化。以下内容参考python文档和网上博客。

介绍

1
The pickle module implements binary protocols for serializing and de-serializing a Python object structure. “Pickling” is the process whereby a Python object hierarchy is converted into a byte stream, and “unpickling” is the inverse operation, whereby a byte stream (from a binary file or bytes-like object) is converted back into an object hierarchy. Pickling (and unpickling) is alternatively known as “serialization”, “marshalling,” 1 or “flattening”; however, to avoid confusion, the terms used here are “pickling” and “unpickling”.

与其他相似库的比较

与marshal比较

Python有一个更原始的序列化模块,称为marshal,但通常pickle应该始终是序列化Python对象的首选方式。 marshal存在主要是为了支持Python的.pyc文件。该pickle模块marshal在以下几个重要方面有所不同:

  • 该pickle模块跟踪已序列化的对象,因此以后对同一对象的引用将不会再次序列化。marshal并不这样做。这对于递归对象和对象共享都有影响。递归对象是包含对其自身的引用的对象。marshal无法处理递归对象,尝试使用marsha处理递归对象将使您的Python解释器崩溃。当要序列化的对象层次结构中的不同位置存在对同一对象的多个引用时,就会发生对象共享。 pickle仅将此类对象存储一次,并确保所有其他引用都指向主副本。共享的对象保持共享状态,这对于可变对象非常重要。

  • marshal不能用于序列化用户定义的类及其实例。 pickle可以透明地保存和恢复类实例,但是类定义必须是可导入的,并且与对象存储时位于同一模块中。

  • 该marshal序列化格式是不能保证整个Python版本移植。因为它的主要工作是支持 .pyc文件,所以Python实现者保留在需要时以非向后兼容的方式更改序列化格式的权利。pickle选择了兼容的pickle协议,并且如果您的数据越过了唯一的突破性更改语言边界,则pickling和unpickling可以处理Python 2到Python 3类型的差异,则可以确保序列化格式在Python版本之间向后兼容。

    与json比较

    pickle协议和JSON (JavaScript Object Notation)之间有基本的区别:

  • JSON是一种文本序列化格式(虽然大多数时间然后将其编码为utf-8,但它输出unicode文本),而pickle是一种二进制序列化格式;

  • JSON是人类可读的,而pickle则不是;

  • JSON是可互操作的,并且在Python生态系统之外被广泛使用,而pickle是特定于Python的;

  • 默认情况下,JSON只能表示Python内置类型的子集,而不能表示自定义类。pickle可以表示大量的Python类型(通过巧妙地使用Python的自省功能,其中的许多会自动实现;可以通过实现特定的对象API解决复杂的情况);

  • 与pickle不同,反序列化不受信任的JSON本身并不会创建代码执行漏洞。

这里也有python的json模块:一个标准的库模块,允许JSON序列化和反序列化。

Data stream format 数据流格式

所使用的数据格式pickle是特定于Python的。这样做的优点是不受外部标准(例如JSON或XDR)的限制(不能表示指针共享);但是,这意味着非Python程序可能无法重建pickling后的Python对象。

默认情况下,pickle数据格式使用相对紧凑的二进制表示形式。如果需要最佳的大小特征,则可以有效地压缩pickling的数据。

该模块pickletools包含用于分析生成的数据流的工具pickle。 pickletools源代码对pickle协议使用的操作码有大量注释。

当前有6种不同的协议可用于pickling。使用的协议越高,读取生成的pickle所需的Python版本越新。

  • Protocol version 0是原始的“人类可读”协议,并且与Python的早期版本向后兼容。

  • Protocol version 1是旧的二进制格式,也与Python的早期版本兼容。

  • Protocol version 2是在Python 2.3中引入的。它提供了更高效的新型es酸洗。参考PEP 307,了解有关协议2带来的改进的信息。

  • Protocol version 3是在Python 3.0中添加的。它具有对bytes对象的显式支持, 并且不能被Python 2.x unpickled。这是Python 3.0–3.7中的默认协议。

  • Protocol version 4是在Python 3.4中添加的。它增加了对非常大的对象的支持,pickling更多种类的对象以及一些数据格式优化。从Python 3.8开始,它是默认协议。参考PEP 3154,获取有关协议4带来的改进的信息。

  • Protocol version 5已在Python 3.8中添加。它增加了对带外数据的支持和对带内数据的加速。参考PEP 574,了解有关协议5带来的改进的信息。

Module Interface 模块接口

pickle提供以下属性:

1
2
3
4
5
6
7
8
9
pickle.HIGHEST_PROTOCOL
An integer, the highest protocol version available. This value can be passed as a protocol value to functions dump() and dumps() as well as the Pickler constructor.

pickle.DEFAULT_PROTOCOL
An integer, the default protocol version used for pickling. May be less than HIGHEST_PROTOCOL. Currently the default protocol is 4, first introduced in Python 3.4 and incompatible with previous versions.

Changed in version 3.0: The default protocol is 3.

Changed in version 3.8: The default protocol is 4.

The pickle module provides the following functions to make the pickling process more convenient: