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 版本的兼容性差。


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


相关文章
|
3天前
|
存储 Java 数据安全/隐私保护
Python----类对象和实例对象
Python----类对象和实例对象
9 2
|
4天前
|
存储 安全 Java
Python中的引用和赋值机制允许变量引用内存中的对象,并通过引用计数来管理对象的生命周期
【5月更文挑战第14天】Python中的变量是对象引用,不存储数据,而是在内存中创建对象。赋值操作创建新变量并使其指向已有对象。引用计数用于管理对象生命周期,引用数为0时对象被回收。理解这些机制对编写高效Python代码很重要。
18 6
|
4天前
|
索引 Python
【Python操作基础】——序列
【Python操作基础】——序列
|
4天前
|
C++ Python
Python中的类与对象
Python中的类与对象
8 1
|
4天前
|
存储 JSON 数据挖掘
python序列化和结构化数据详解
python序列化和结构化数据详解
14 0
|
4天前
|
数据采集 数据挖掘 测试技术
python、R语言ARIMA-GARCH分析南方恒生中国企业ETF基金净值时间序列分析
python、R语言ARIMA-GARCH分析南方恒生中国企业ETF基金净值时间序列分析
|
4天前
|
vr&ar Python
Python自激励阈值自回归(SETAR)、ARMA、BDS检验、预测分析太阳黑子时间序列数据
Python自激励阈值自回归(SETAR)、ARMA、BDS检验、预测分析太阳黑子时间序列数据
|
4天前
|
Python
Python随机波动性SV模型:贝叶斯推断马尔可夫链蒙特卡洛MCMC分析英镑/美元汇率时间序列数据|数据分享
Python随机波动性SV模型:贝叶斯推断马尔可夫链蒙特卡洛MCMC分析英镑/美元汇率时间序列数据|数据分享
|
4天前
|
机器学习/深度学习 Python
【Python机器学习专栏】时间序列数据的特征工程
【4月更文挑战第30天】本文探讨了时间序列数据的特征工程,强调其在捕捉季节性、揭示趋势、处理异常值和提升模型性能中的重要性。介绍了滞后特征、移动窗口统计特征、时间戳特征、频域特征和波动率特征等方法,并提供了Python实现示例。通过有效特征工程,可提高时间序列分析的准确性和预测可靠性。
|
1天前
|
Python
10个python入门小游戏,零基础打通关,就能掌握编程基础_python编写的入门简单小游戏
10个python入门小游戏,零基础打通关,就能掌握编程基础_python编写的入门简单小游戏