高级 Python 开发课程
第 章
>
第 级
序列化模块
Marshal 和 Pickle 模块
目标
前往服务站,并确保使用 JSON 模块格式化文件后数据被正确存储。
沿着小路继续前进,我们会发现几个车站正在监控为未来收成而开发的土地的水资源分配和土壤质量。为了处理数据,将数据序列化是高效的方法。虽然使用 Json 作为通用解决方案可以有效,但也有一些 Python 专用的序列化方法,比如 Marshal 和 Pickle 模块。Marshal 模块通过将数据转换为二进制来实现快速序列化/反序列化,适用于更简单的数据传输。Pickle 模块虽然速度较慢,但设计用于处理更复杂的数据结构,具有更高的灵活性,非常适合处理较大或优先的数据结构。
要使用 Marshal 和 Pickle 模块,请通过如下代码导入它们的函数:import marshal 和 import pickle。在我们的例子中,我们将使用以下函数:
marshal.dumps(): 将数据序列化为二进制格式,专为 Python 内部速度设计。它接受一个参数,即你希望序列化的数据,仅限于基本数据类型。marshal.loads(): 将二进制数据反序列化为 Python 可读的数据类型,功能有限但执行速度快。它接受一个参数,即你希望反序列化的数据。pickle.DEFAULT_PROTOCOL: 检查你所使用的 Python 版本中 Pickle 序列化的默认协议版本。协议会影响数据的序列化方式。pickle.HIGHEST_PROTOCOL: 检查你所使用的 Python 版本中 Pickle 序列化可用的最高协议版本。协议会影响数据的序列化方式。pickle.dumps(): 根据所选协议将复杂的 Python 数据结构序列化为二进制格式。它接受两个参数,即你希望序列化的数据和所使用的协议版本。pickle.loads(): 将二进制数据反序列化为 Python 可读的数据类型,对 Python 对象具有强大的处理能力。它接受一个参数,即你希望反序列化的数据。
除了这些模块和函数,我们还将使用一个名为 pprint 的格式化模块,我们将通过 from pprint import pprint 导入它。这使我们能够使用 pprint() 函数来格式化诸如字典等数据结构,从而清晰地显示信息。
首先,走到小型监控站内标有光 X 标记的地方,并面向计算机终端。该站点监控着即将用于种植作物的附近地形的水压和土壤状况。有一个名为 reading 的常量,其中包含了车站收集的 Python 数据。
创建一个名为 data 的变量,并将 marshal.dumps() 函数的返回值存入其中,参数为 reading。示例如下:data = marshal.dumps(reading)。然后使用预先编写的 display() 函数和 data 变量来查看序列化后的变量数据。
走出该站,前往标有金色 X 标记的地方,使用 open() 函数打开门以进入办公室。走到终端前标有光 X 标记的地方,并反序列化你刚刚序列化的数据。创建一个名为 output 的变量,并将 marshal.loads() 的返回值存入其中,参数为之前的 data 变量。使用 write() 函数,并将 output 作为参数,以访问你从监控站收集的序列化数据。
走向办公室内铺有蓝色地毯处标有光 X 标记的位置,在终端上我们将验证协议,以确定 Pickle 模块在处理数据时将使用哪种序列化方式。在预先编写的 write() 函数中,将参数设置为 pickle.DEFAULT_PROTOCOL 和 pickle.HIGHEST_PROTOCOL。这将验证当前的序列化协议以及当前可用的最新序列化协议。
继续前往蓝色地毯上标有暗 X 标记的区域,现在我们已经确认了协议,可以验证存储的数据。几个月来数据已经被收集并存储在一个名为 samples 的常量中。创建三个变量,分别命名为:sereal_0、sereal_2 和 sereal_5,我们将使用这些变量来验证可用的三种序列化协议。协议 0 为可读的 ASCII 格式,效率不高;协议 2 为更高效的二进制格式;而协议 5 则是添加了最多高级特性的最新协议。
我们将存储 pickle.dumps() 的返回值,并将 sample 常量与对应于变量名上数字的 protocol 参数一起传入。例如,对于 sereal_0,我们将 protocol 设置为 0,示例如下:sereal_0 = pickle.dumps(samples, protocol=0)。使用 sereal_0、sereal_2 和 sereal_5 变量与预先编写的 display() 函数一起,来验证每种协议下序列化的不同效果。
走到铺有红色地毯的区域标有光 X 标记的地方,并面向终端,覆盖赋值 output 变量,将其设置为 pickle.loads() 的返回值,参数为 sereal_5,以便反序列化到目前为止收集的样本数据。使用 display() 函数,并将 pprint() 函数与 output 变量一起传入,以查看数据。示例如下:await player.display(pprint(output))。注意终端显示的每个月的评分,以便稍后绘制图表。
走向铺有红色地毯的区域标有暗 X 标记的地方,并面向桌子,在预先编写的 write() 函数中,按正确的顺序添加你之前在终端中记录的每个月的评分。将它们作为带有 "" 引号的字符串添加,按照函数中所列出的顺序,直至完成本关。