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月前
|
安全 大数据 程序员
Python operator模块的methodcaller:一行代码搞定对象方法调用的黑科技
`operator.methodcaller`是Python中处理对象方法调用的高效工具,替代冗长Lambda,提升代码可读性与性能。适用于数据过滤、排序、转换等场景,支持参数传递与链式调用,是函数式编程的隐藏利器。
321 4
|
安全 JavaScript Java
Python中None与NoneType的真相:从单例对象到类型系统的深度解析
本文通过10个真实场景,深入解析Python中表示“空值”的None与NoneType。从单例模式、函数返回值,到类型注解、性能优化,全面揭示None在语言设计与实际编程中的核心作用,帮助开发者正确高效地处理“无值”状态,写出更健壮、清晰的Python代码。
4472 3
|
Python
解决Python中AttributeError:'image'对象缺少属性'read_file'的问题策略。
通过上述策略综合考虑,您将能够定位问题并确定如何解决它。记住,Python社区很庞大,也很乐于帮助解决问题,因此不要害怕在求助时提供尽可能多的上下文和您已经尝试过的解决方案。
336 0
|
Python
解决Python报错:DataFrame对象没有concat属性的多种方法(解决方案汇总)
总的来说,解决“DataFrame对象没有concat属性”的错误的关键是理解concat函数应该如何正确使用,以及Pandas库提供了哪些其他的数据连接方法。希望这些方法能帮助你解决问题。记住,编程就像是解谜游戏,每一个错误都是一个谜题,解决它们需要耐心和细心。
694 15
|
人工智能 Python
[oeasy]python083_类_对象_成员方法_method_函数_function_isinstance
本文介绍了Python中类、对象、成员方法及函数的概念。通过超市商品分类的例子,形象地解释了“类型”的概念,如整型(int)和字符串(str)是两种不同的数据类型。整型对象支持数字求和,字符串对象支持拼接。使用`isinstance`函数可以判断对象是否属于特定类型,例如判断变量是否为整型。此外,还探讨了面向对象编程(OOP)与面向过程编程的区别,并简要介绍了`type`和`help`函数的用法。最后总结指出,不同类型的对象有不同的运算和方法,如字符串有`find`和`index`方法,而整型没有。更多内容可参考文末提供的蓝桥、GitHub和Gitee链接。
411 11
|
安全 测试技术 开发者
Python中的“空”:对象的判断与比较
在Python开发中,判断对象是否为“空”是常见操作,但其中暗藏诸多细节与误区。本文系统梳理了Python中“空”的判定逻辑,涵盖None类型、空容器、零值及自定义对象的“假值”状态,并对比不同判定方法的适用场景与性能。通过解析常见误区(如混用`==`和`is`、误判合法值等)及进阶技巧(类型安全检查、自定义对象逻辑、抽象基类兼容性等),帮助开发者准确区分各类“空”值,避免逻辑错误,同时优化代码性能与健壮性。掌握这些内容,能让开发者更深刻理解Python的对象模型与业务语义交集,从而选择最适合的判定策略。
638 5
|
存储 数据采集 大数据
Python推导式进阶指南:优雅初始化序列的科学与艺术
本文系统讲解Python推导式的用法与技巧,涵盖列表、字典、集合推导式及生成器表达式。通过代码示例和性能对比,展示推导式在数据结构初始化中的优势:简洁高效、执行速度快30%-50%。文章分析基础语法、核心应用场景(如序列构造、键值对转换、去重运算)及嵌套使用,并探讨使用边界与最佳实践,强调可读性优先原则。最后指出,合理运用推导式能显著提升代码质量和处理效率,同时避免过度复杂化的陷阱。
467 0
|
存储 C++ 索引
Python 序列类型(1)
【10月更文挑战第8天】
254 1
|
存储 编译器 索引
Python 序列类型(2)
【10月更文挑战第8天】
201 0
Python 序列类型(2)
|
存储 索引 Python
Python中序列类型 (Sequence Types)
【8月更文挑战第2天】
696 4

推荐镜像

更多