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


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


相关文章
|
22天前
|
Python
python对象模型
这篇文章介绍了Python中的对象模型,包括各种内置对象类型如数字、字符串、列表、字典等,以及如何使用`type()`函数来查看变量的数据类型。
|
12天前
|
机器学习/深度学习 数据采集 算法
时间序列结构变化分析:Python实现时间序列变化点检测
在时间序列分析和预测中,准确检测结构变化至关重要。新出现的分布模式往往会导致历史数据失去代表性,进而影响基于这些数据训练的模型的有效性。
29 1
|
22天前
|
Python
探索Python中的魔法方法:打造你自己的自定义对象
【8月更文挑战第29天】在Python的世界里,魔法方法如同神秘的咒语,它们赋予了对象超常的能力。本文将带你一探究竟,学习如何通过魔法方法来定制你的对象行为,让你的代码更具魔力。
37 5
|
20天前
|
机器学习/深度学习 算法 数据挖掘
6种有效的时间序列数据特征工程技术(使用Python)
在本文中,我们将探讨使用日期时间列提取有用信息的各种特征工程技术。
73 0
|
12天前
|
机器学习/深度学习 索引 Python
python之序列
python之序列
134 59
|
7天前
|
存储 Java
Java编程中的对象序列化与反序列化
【9月更文挑战第12天】在Java的世界里,对象序列化与反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何通过实现Serializable接口来标记一个类的对象可以被序列化,并探索ObjectOutputStream和ObjectInputStream类的使用,以实现对象的写入和读取。我们还将讨论序列化过程中可能遇到的问题及其解决方案,确保你能够高效、安全地处理对象序列化。
|
22天前
|
机器学习/深度学习 分布式计算 大数据
几行 Python 代码就可以提取数百个时间序列特征
几行 Python 代码就可以提取数百个时间序列特征
|
20天前
|
存储 程序员 Python
Python类的定义_类和对象的关系_对象的内存模型
通过类的定义来创建对象,我们可以应用面向对象编程(OOP)的原则,例如封装、继承和多态,这些原则帮助程序员构建可复用的代码和模块化的系统。Python语言支持这样的OOP特性,使其成为强大而灵活的编程语言,适用于各种软件开发项目。
15 1
|
17天前
|
存储 Java
Java编程中的对象序列化与反序列化
【9月更文挑战第2天】在Java的世界里,对象序列化和反序列化就像是给数据穿上了一件隐形的斗篷。它们让数据能够轻松地穿梭于不同的系统之间,无论是跨越网络还是存储在磁盘上。本文将揭开这层神秘的面纱,带你领略序列化和反序列化的魔法,并展示如何通过代码示例来施展这一魔法。
14 0
|
30天前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。