Python序列化和反序列化

一.序列化和反序列化

        在Python中,序列化(Serialization)和反序列化(Deserialization)是处理对象数据的过程,主要用于对象的存储或网络传输。

序列化(Serialization)

        序列化是将Python对象转换成一个字节流(或称为序列化后的表示)的过程,这个字节流可以被写入磁盘文件或通过网络发送。序列化使得对象的状态信息能够被保存,之后可以在需要的时候恢复对象。pickle.dump(obj, file, [,protocol]) 函数就是执行序列化的操作,各参数意义如下:

  • obj:要被序列化的Python对象。
  • file:文件对象,表示序列化后的数据将被写入的文件或类文件对象(如BytesIO)。
  • protocol(可选):指定序列化使用的协议版本,默认值是 pickle.HIGHEST_PROTOCOL,不同的协议影响了生成的字节流的兼容性和效率。

反序列化(Deserialization)

反序列化则是将之前序列化得到的字节流恢复成原来的Python对象的过程。这使得从磁盘文件读取或网络接收的数据能再次成为可操作的对象。对应的,pickle.load(file) 函数用于执行反序列化,参数意义如下:

  • file:文件对象,从该文件中读取之前序列化的数据并恢复成Python对象。

例子:

        假设我们有一个简单的Python对象,我们可以通过以下步骤进行序列化和反序列化:

序列化示例

import pickledata = {'name': 'Alice', 'age': 30}
with open('example.pickle', 'wb') as handle:pickle.dump(data, handle, protocol=pickle.HIGHEST_PROTOCOL)

反序列化示例

import picklewith open('example.pickle', 'rb') as handle:data_loaded = pickle.load(handle)
print(data_loaded)  # 输出: {'name': 'Alice', 'age': 30}

        通过序列化和反序列化,我们可以轻松地存储复杂的数据结构或在网络间传递这些数据,这对于长期存储、数据交换或分布式计算等场景非常有用。但需要注意的是,pickle模块不是安全的,不应该用来序列化不可信的数据,因为它可以执行任意代码。

pickle序列化实例

下面是使用 pickle 进行序列化和反序列化的两个简单示例。

示例 1: 序列化与反序列化一个简单列表

序列化过程:

import pickle# 需要被序列化的简单Python对象 - 一个列表
my_list = [1, 'apple', 3.14]# 打开一个文件用于写入序列化后的数据
with open('example_pickle_list.pkl', 'wb') as handle:# 使用pickle的dumps或dump方法进行序列化# dump直接写入文件句柄,dumps则返回一个bytes对象pickle.dump(my_list, handle, protocol=pickle.HIGHEST_PROTOCOL)

在此过程中,my_list 这个包含整数、字符串和浮点数的列表被转换成一个字节流,并存储到 example_pickle_list.pkl 文件中。

反序列化过程:

import pickle# 打开之前存储的文件以读取并反序列化数据
with open('example_pickle_list.pkl', 'rb') as handle:# 使用pickle的loads或load方法进行反序列化# load直接从文件句柄读取并还原对象,loads则从bytes对象还原loaded_list = pickle.load(handle)print(loaded_list)  # 输出: [1, 'apple', 3.14]

通过 pickle.load(),我们能够从二进制文件中恢复出原始的 Python 列表对象。

示例 2: 序列化与反序列化自定义类的对象

假设有一个简单的自定义类 Person

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __repr__(self):return f"Person(name='{self.name}', age={self.age})"

序列化过程:

import pickle# 创建一个Person对象
person_instance = Person("Alice", 30)# 序列化Person对象到文件
with open('example_pickle_person.pkl', 'wb') as person_file:pickle.dump(person_instance, person_file, protocol=pickle.HIGHEST_PROTOCOL)

反序列化过程:

import pickle# 反序列化解回Person对象
with open('example_pickle_person.pkl', 'rb') as person_file:loaded_person = pickle.load(person_file)print(loaded_person)  # 输出: Person(name='Alice', age=30)

在这个例子中,即使 Person 类是一个自定义类,pickle 也能够成功地序列化其实例,并在之后正确地反序列化回原始对象状态。

序列化之后的数据形式

        使用 pickle 序列化数据后,原始的 Python 对象会被转换成一个二进制格式的字节流。这个字节流包含了对象的类型信息、属性及其值,以及可能的引用信息,以便能够完全重建原始对象。由于它是二进制格式,直接查看时不会像文本格式那样直观易读。

如果你尝试打印出 pickle.dumps() 方法处理后的结果,你会看到类似下面这样的输出,显示为字节序列:

b'\x80\x04\x95\x16\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x06Person\x94\x93\x94)\x81\x94}\x94(\x8c\x04name\x94\x8c\x05Alice\x94\x8c\x03age\x94K\x1eub.'

        这段二进制数据中包含了Python解释器如何重建对象的指令。每个字节或字节序列代表了特定的含义,比如对象类型、字符串长度、整数值等。例如,\x80\x04 是 pickle 协议版本的标识,\x95\x16 可能指示全局名称查找,\x8c 引入了一个字符串,后面跟着字符串长度和内容,\x94 表示结束,\x93 开始构建一个新对象,等等。

        由于这些信息对人类来说难以直接解读,通常我们不会直接查看或编辑这些序列化后的数据,而是依赖 pickle.load()pickle.loads() 来自动解析这些字节流,恢复成原始的 Python 对象。

二.序列化的实现原理

        Python中的pickle模块实现序列化和反序列化的原理主要是通过对象的递归分析及构造。以下是其工作流程的基本概述:

序列化过程(dump)

  1. 检查对象类型:当pickle.dump()被调用时,pickle首先检查要序列化的对象类型。Python的基本数据类型(如整数、浮点数、字符串等)有预定义的序列化方式。对于复杂类型(如列表、字典、自定义类的实例等),则需要更复杂的处理。

  2. 递归处理:对于复杂对象,pickle会递归地进入对象的每个元素,对它们进行同样的检查和序列化过程。这意味着如果一个对象包含其他对象,这些内部对象也会被序列化。

  3. 生成二进制流:对于每种类型,pickle使用一种特定的编码方案将其转换为一系列的字节。这个过程包括类型标识符、对象的属性或元素值等信息。例如,一个字典会被编码为它的键值对序列,每个键值对又进一步被序列化。

  4. 写入文件或字节流:最终的字节流按照指定的协议格式编码后,被写入到文件或其他输出流中。协议决定了如何编码类型信息和数据,不同的协议版本提供了向前或向后的兼容性。

反序列化过程(load)

  1. 读取二进制流:当使用pickle.load()从文件或字节流读取时,首先读取并解析字节流中的类型标识符和数据。

  2. 重建对象:根据解析出的类型标识符,pickle会创建相应的Python对象,并根据字节流中的数据填充对象的属性或内容。对于复杂对象,这一过程也是递归进行的,先创建容器对象,然后在其内部重建子对象。

  3. 处理引用:在序列化复杂数据结构时,如果对象之间存在循环引用或重复引用,pickle会通过引用计数或ID映射来处理这些情况,确保反序列化后的对象结构与原始结构一致。

  4. 返回对象:一旦所有对象都被正确重建,pickle.load()会返回最顶层的对象,即原始数据的完全复制品。

安全性考虑

        虽然pickle功能强大,但由于它能够执行任意的Python代码(特别是在处理自定义类和其他可执行代码时),因此使用非可信来源的数据进行反序列化可能存在安全风险。因此,在处理外部输入的数据时,推荐使用更安全的序列化库,如jsonyaml,或者确保有适当的安全措施来验证和清理数据。

三.为什么需要用到序列化

序列化在软件开发和系统设计中扮演着重要角色,主要有以下几个原因:

  1. 数据持久化:当程序运行时,内存中的数据是暂时的,程序关闭后数据就会丢失。序列化允许我们将这些数据转换为可以存储在磁盘上的格式,如文件,从而实现数据的持久保存。这样,即使程序重启或系统关闭,之前的状态和数据仍然可以恢复。

  2. 跨平台/进程通信:在分布式系统或多个程序之间交换数据时,序列化是必需的。通过将对象转换为通用的格式(如JSON、XML或二进制流),可以在不同语言编写的系统之间轻松共享数据,因为这些格式是跨平台理解的。

  3. 网络传输:在进行网络通信时,如通过HTTP请求或RPC(远程过程调用),数据需要被序列化成适合网络传输的格式。这不仅包括基本类型,还包括复杂对象结构,确保接收方能够准确无误地重建发送方的意图。

  4. 缓存和复制:序列化有助于实现数据缓存,比如将计算结果序列化后存储,以便下次直接使用而无需重新计算。同时,在分布式系统中,对象的序列化可以用来辅助数据复制,确保数据的一致性。

  5. 可移植性和兼容性:序列化使得应用程序状态或配置可以轻松地在不同环境之间迁移,无论是不同版本的同一程序,还是完全不同系统之间的数据交换,都提高了软件的灵活性和可维护性。

  6. 批处理和任务队列:在需要将任务分解并通过消息队列分发时,任务及其所需的数据常常需要被序列化,以便在队列中存储和传输,然后在另一个进程中反序列化并处理。

        综上所述,序列化是现代软件开发中不可或缺的技术,它简化了数据存储、传输和交换的复杂性,增强了系统的灵活性和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/39370.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7.x86游戏实战-C++实现跨进程读写-跨进程写内存

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 上一个内容:6.x86游戏实战-C实现跨进程读写-通过基址读取人物状态标志位 上一个内容通过基…

深层神经网络

深层神经网络 深层神经网络 深度神经网络(Deep Neural Networks,DNN)可以理解为有很多隐藏层的神经网络,又被称为深度前馈网络(DFN),多层感知机(Multi-Layer perceptron&#xff0c…

ghost恢复?电脑文件恢复如何操作?电脑数据恢复工具!5款!

在数字化时代,电脑数据的价值日益凸显。然而,数据丢失、误删、系统崩溃等问题时有发生,给个人和企业带来巨大损失。本文将为您详细介绍Ghost恢复方法,同时推荐五款高效的电脑数据恢复工具,助您轻松应对数据丢失的困扰。…

使用归档实用工具怎么打不开 mac上好用的解压软件 归档实用工具打不开怎么回事 mac 归档实用工具 苹果电脑好用的压缩软件有哪些

Mac系统自带的 “归档实用工具”,集成在系统右键菜单中,包含了文件压缩和压缩包解压功能。很多mac小伙伴会发现有些文件使用归档实用工具打不开。由于专利和软件开源问题,该工具目前仅支持ZIP格式的压缩和解压。同时,对于一些在Wi…

深入探讨数据结构:基础理论与应用实践

前言 数据结构是计算机科学的重要组成部分,是编程与算法设计的基础。本文将系统地介绍数据结构的基础概念、常见类型、具体实现及其在实际开发中的应用,帮助读者深入理解这一核心领域。 一、数据结构的基本概念 数据结构指的是计算机中数据的组织、管…

推广旅游卡项目,一个月创收十几万,为何说旅游卡项目堪称盈利利器?

推广旅游卡项目,一月个创收十几万,为何说旅游卡项目堪称盈利利器? 其精髓恰在于那十六字真言:即时收益,高额利润,操作简便,粉丝友好。接下来,我将从推广人员的视角,为您…

Microsoft SQL Server 2019安装和设置用户密码

1、免费下载两个安装包 SQL2019-SSEI-Dev 地址:https://www.microsoft.com/en-us/sql-server/sql-server-downloads SSMS-Setup-CHS 地址:https://aka.ms/ssmsfullsetup 安装具体不在阐述了,可以参考我这篇文章:SQL Server 2019安装详细教程 2、以W…

开发常见的http状态码.——400,401,403,404,500,501,503,状态码大全!

目录 一. 1开头的(临时信息响应码) 二. 2开头的(成功信息码) 三. 3开头的(重定向信息码) 四. 4开头的(客户端错误信息码) 五. 5开头的(服务器内部错误信息码) 一. 1开头的(临时信息响应码) 100:继续请求。示意请求者应当继续发送请求,客户端返回此码…

Cookie的默认存储路径以及后端如何设置

问题场景 最近在写一个前后端分离的项目,需要跨域,前端开发同学遇到一个问题一直报错,本质上就是后端返回的cookie中的sessionID在前端发送http请求时无法被请求自动携带,每次htttpRequest都被后端识别为一个新的session&#xf…

Spring MVC数据绑定和响应——数据回写(二)JSON数据的回写

项目中已经导入了Jackson依赖,可以先调用Jackson的JSON转换的相关方法,将对象或集合转换成JSON数据,然后通过HttpServletResponse将JSON数据写入到输出流中完成回写,具体步骤如下。 1、修改文件DataController.java,在…

verilog 参数用法

参数比较运算 localparam QPLL_FBDIV_IN (QPLL_FBDIV_TOP 16) ? 10b0000100000 : (QPLL_FBDIV_TOP 20) ? 10b0000110000 :(QPLL_FBDIV_TOP 32) ? 10b0001100000 :(QPLL_FBDIV_TOP 40) ? 10b0010000000 :(QPLL_FBDIV_TOP 64) ? 10b0011100000 :(QPLL_FBDIV_TO…

昇思25天学习打卡营第04天 | 数据集 Dataset

昇思25天学习打卡营第04天 | 数据集 Dataset 文章目录 昇思25天学习打卡营第04天 | 数据集 Dataset数据集加载数据集迭代数据集的变换shufflemapbatch 自定义数据集可随机访问数据集对象可迭代数据集生成器 总结打卡 数据集Dataset对原始数据进行封装、变换,为神经网…

Linux 静态库 和 动态库

在Linux系统上,库文件用于共享和重用代码。根据使用方式和链接方式的不同,库文件可以分为静态库和动态库。 静态库(Static Library) 静态库是在编译时被嵌入到最终可执行文件中的库。静态库的扩展名通常是.a。 特点 独立性&am…

ADOP带你了解:SFP 光模块:构建高速网络的关键技术

在数字化时代,企业运营的效率往往取决于数据传输的速度。因此,构建一个可靠的网络基础架构至关重要。本指南深入探讨了小型可插拔(SFP)光收发器的关键作用,这些设备确保了网络中数据的高效和安全流动。SFP光收发器的设…

【Rust入门教程】hello world程序

文章目录 前言Hello World程序运行总结 前言 对于学习任何一种新的编程语言,我们都会从编写一个简单的Hello World程序开始。这是一个传统,也是一个开始。在这篇文章中,我们将一起学习如何在Rust中编写你的第一个程序:Hello Worl…

【C语言内存函数】

目录 1.memcpy 使用 模拟实现 2.memmove 使用 模拟实现 3.memset 使用 4.memcmp 使用 1.memcpy 使用 void * memcpy ( void * destination, const void * source, size_t num );目的地址 源地址 字节数 destination:指向要复制内…

20240703 每日AI必读资讯

🤖爆火Character AI惨遭阉割 美国00后集体“失恋” - Character AI曾是00后最火爆的社交软件,但用户发现对话模型变得冷淡,失去趣味。 - 用户流失严重,面临成本高、竞争激烈的挑战,甚至遭到挖角。 - 尽管困难重重&a…

淘宝API接口开发系列:淘宝订单详情API接口与物流电子面单API接口概述

淘宝订单详情API接口与物流电子面单API接口概述 在电子商务领域,API(应用程序接口)扮演着至关重要的角色,它们使得不同的系统能够相互通信,实现数据的共享和交换。淘宝作为国内最大的电商平台之一,其提供的…

C# 多线程造成CPU占用率高

当线程多的时候就会造成CPU内存占用率过高 private void button1_Click(object sender, EventArgs e){Thread TH1, TH2, TH3, TH4, TH5;TH1 new Thread(Thread1){IsBackground true};TH2 new Thread(Thread2){IsBackground true};TH3 new Thread(Thread3){IsBackground t…

最小步数模型——AcWing 1107. 魔板

最小步数模型 定义 最小步数模型通常是指在某种约束条件下,寻找从初始状态到目标状态所需的最少操作或移动次数的问题。这类问题广泛存在于算法、图论、动态规划、组合优化等领域。具体来说,它涉及确定一个序列或路径,使得按照特定规则执行…