Python 对象的序列和反序列化(下)

简介: 在 Python 中提供了一个 pickle 模块,pickle 模块实现了二进制协议。支持我们的对象数据的序列和反序列化。

3 pickle 模块的优缺点


优点

  • 可以用来存储 Python 对象。我们不需要一次又一次地构造相同的对象。我们将创建一个对象,然后将其保存到磁盘中(pickling),以后再从磁盘中加载这个对象(unpickling),而不需要再次创建这个对象。
  • 在机器学习中非常有用。一个机器学习模型是在一个非常大的数据集上训练的,而训练一个模型需要消耗大量的时间。因此,如果我们必须训练相同的模型,这将不是一个好的选择。为了避免或减少时间和艰苦的工作,pickling 是非常有用的。我们只需要训练一次我们的模型,然后将其保存在本地磁盘中,当我们需要测试我们的模型时,我们可以直接从磁盘中加载它,而不需要再次训练它。
  • Python 的 pickle 模块比 json 模块可以序列化更多的类型。然而,并不是所有的东西都可以被 picklable。不可 pickable 对象的列表包括数据库连接、开放网络套接字正在运行的线程


缺点

  • 缺乏安全性。避免从未知来源 unpickling 数据,因为它们可能包含恶意的或错误的数据。

根据官方文档:“pickle 模块并不安全,只能 unpickling 你信任的数据。黑客有可能构建恶意的 pickled 数据,然后在解压过程中执行任意代码。不要 unpickle 可能来自不信任的来源或可能被篡改的数据。如果你需要确保数据没有被篡改,请考虑用hmac 签名。如果你正在处理不受信任的数据,更安全的序列化格式,那么 json 可能更合适。”


  • 兼容性太差。由于它只针对 Python,所以它不能保证跨语言的兼容性。甚至不同的 Python 版本之间也不兼容。这意味着在 Python 2.x 版本中完成的 pickling 可能在 Python 3.x 版本中无法工作。


4 扩展 pickle 模块的 dill 库


dill 模块扩展了 pickle 的功能。根据官方文档,它可以让你序列化一些不太常见的类型,如带 yield函数嵌套函数lambdas 和其他许多类型。


为了测试这个模块,你可以尝试 pickle 一个 lambda 函数。

import pickle
square = lambda x: x * x
my_pickle = pickle.dumps(square)

运行上述代码,会得到一个异常,因为 Python pickle 模块不能序列化一个 lambda 函数。


image.png


如果用 dill 库来序列化,如下:

import dill
square = lambda x: x * x
my_pickle = dill.dumps(square)
print(my_pickle)


此时可以看到不会报错:

$ python dill_test.py 
b'\x80\x04\x95\xdb\x00\x00\x00\x00\x00\x00\x00\x8c\ndill._dill\x94\x8c\x10_create_function\x94\x93\x94(h\x00\x8c\x0c_create_code\x94\x93\x94(K\x01K\x00K\x00K\x01K\x02KCC\x08|\x00|\x00\x14\x00S\x00\x94N\x85\x94)\x8c\x01x\x94\x85\x94\x8c/E:\\Coding Workspaces\\PythonScripts\\dill_test.py\x94\x8c\x08<lambda>\x94K\x03C\x00\x94))t\x94R\x94c__builtin__\n__main__\nh\nNNt\x94R\x94}\x94}\x94\x8c\x0f__annotations__\x94}\x94s\x86\x94b.'

5 总结

在本文中,我们了解了 Python 中的 pickling(对象序列化) 和 unpickling (反序列化)操作,这些操作对于存储对象以供以后使用很有用。介绍了内置的 pickle 模块提供了诸如 load()loads()dump()dumps() 之类的方法,用于将 Python 对象与字节流之间的相互转换。


因为 Python 中一切皆对象的特点,所以 Python 中的元组、字典、列表,甚至 Python 类和函数也可以被序列化和反序列化。但它可能不支持跨语言、多 Python 版本的兼容性差。


另外,为了安全性,也应避免从未知来源解压,因为它们可能包含恶意的、错误的数据。


相关文章
|
12天前
|
存储 算法 数据挖掘
【2023年中国高校大数据挑战赛 】赛题 B DNA 存储中的序列聚类与比对 Python实现
本文介绍了2023年中国高校大数据挑战赛赛题B的Python实现方法,该赛题涉及DNA存储技术中的序列聚类与比对问题,包括错误率分析、序列聚类、拷贝数分布图的绘制以及比对模型的开发。
26 1
【2023年中国高校大数据挑战赛 】赛题 B DNA 存储中的序列聚类与比对 Python实现
|
12天前
|
机器学习/深度学习 数据采集 算法
【优秀python算法毕设】基于python时间序列模型分析气温变化趋势的设计与实现
本文介绍了一个基于Python的时间序列模型,用于分析和预测2021-2022年重庆地区的气温变化趋势,通过ARIMA和LSTM模型的应用,揭示了气温的季节性和趋势性变化,并提供了对未来气温变化的预测,有助于气象预报和相关决策制定。
【优秀python算法毕设】基于python时间序列模型分析气温变化趋势的设计与实现
|
11天前
|
程序员 Ruby Python
Python里的类和对象是什么?
本文介绍了Python中面向对象编程的核心概念——类与对象。类作为一种“蓝图”,定义了一组属性和方法,用于描述一类对象的共同特征与行为。通过类可以创建具体的对象实例,每个对象拥有类所定义的属性和方法。文章通过`Human`类的例子详细展示了如何定义类、初始化对象及其属性、定义方法,以及如何给对象添加自定义属性。此外,还介绍了如何通过类创建多个具有不同特性的对象实例,并探讨了属性覆盖和使用`@property`装饰器实现只读属性的方法。
|
13天前
|
算法 Python
【Leetcode刷题Python】剑指 Offer 33. 二叉搜索树的后序遍历序列
本文提供了一种Python算法,用以判断给定整数数组是否为某二叉搜索树的后序遍历结果,通过识别根节点并递归验证左右子树的值是否满足二叉搜索树的性质。
11 3
|
12天前
|
Python
【Python】如何判断时间序列数据是否为平稳时间序列或非平稳时间序列?
本文介绍了如何通过观察均值和方差的变化、ADF单位根检验、KPSS检验以及差分操作来判定时间序列数据是否为平稳或非平稳,并提供了Python代码示例进行实际检验。
26 0
【Python】如何判断时间序列数据是否为平稳时间序列或非平稳时间序列?
|
13天前
|
数据采集 算法 数据挖掘
【2023 年第二届钉钉杯大学生大数据挑战赛】 初赛 B:美国纽约公共自行车使用量预测分析 问题三时间序列预测Python代码分析
本文介绍了2023年第二届钉钉杯大学生大数据挑战赛初赛B题的Python代码分析,涉及美国纽约公共自行车使用量的时间序列预测、网络分析和聚类分析。
22 0
【2023 年第二届钉钉杯大学生大数据挑战赛】 初赛 B:美国纽约公共自行车使用量预测分析 问题三时间序列预测Python代码分析
|
14天前
|
算法 Python
【Leetcode刷题Python】300. 最长递增子序列
LeetCode 300题 "最长递增子序列" 的两种Python解决方案:一种使用动态规划,另一种使用贪心算法结合二分查找。
25 1
|
4天前
|
JSON 缓存 安全
Python pickle 二进制序列化和反序列化 - 数据持久化
Python pickle 二进制序列化和反序列化 - 数据持久化
11 0
|
13天前
|
Python
【python笔记】使用zip函数迭代多个可迭代对象
【python笔记】使用zip函数迭代多个可迭代对象
|
14天前
|
Python
【Leetcode刷题Python】674. 最长连续递增序列
LeetCode 674题 "最长连续递增序列" 的Python解决方案,使用动态规划算法找出给定整数数组中最长连续递增子序列的长度。
32 0