Python对象序列化与反序列化:从入门到实战

VIP/
在Python编程中,我们经常面临这样一个问题:如何将内存中正在运行的对象(比如一个包含了复杂数据的类实例)保存下来,或者通过网络发送给另一台机器?由于内存中的对象是动态的、临时的,无法直接存储或传输,这就引出了序列化(Serialization)与反序列化(Deserialization)这两个核心概念。
简单来说,序列化就像是给鲜活的对象拍一张“定妆照”(转换为字节流或字符串),使其能够被保存到硬盘或通过网络发送;而反序列化则是根据这张“照片”完美复原出原来的对象。本文将深入浅出地讲解Python中实现类序列化的几种主流方式,并通过代码示例带你掌握这一关键技术。
一、什么是序列化与反序列化
序列化,即将内存中的Python对象转换为可存储(如保存到文件)或可传输(如通过网络发送)的格式(如二进制流、JSON字符串)的过程。反序列化则是其逆过程,即将存储的或接收到的数据重新恢复为内存中的Python对象。这一对技术是数据持久化、网络通信(如Web API)和缓存系统(如Redis)的基石。
二、Python内置双雄:pickle与json
Python提供了两个强大的内置模块来处理序列化:picklejson。它们各有千秋,适用于不同的场景。
1. 

Pickle:Python专属的“对象保鲜术” pickle是Python特有的二进制序列化模块。它的最大优势是“全能”,几乎可以序列化任何Python对象,包括自定义类的实例、函数、甚至复杂的集合类型(如set)。它能完美保留对象的类型和内部结构。
以下代码展示了如何使用pickle模块对自定义的User类实例进行序列化和反序列化。可以看到,反序列化后得到的对象与原对象完全一致,其属性和方法都能正常调用。
代码
import pickle

class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def introduce(self):
        return f"我是{self.name},今年{self.age}岁。"

# 1. 创建对象
user = User("Alice", 25)

# 2. 序列化:对象 -> 二进制文件
with open("user.pkl", "wb") as f:  # 注意:必须以二进制写模式(wb)打开
    pickle.dump(user, f)
print("对象已通过Pickle序列化并保存。")

# 3. 反序列化:二进制文件 -> 对象
with open("user.pkl", "rb") as f:  # 注意:必须以二进制读模式(rb)打开
    loaded_user = pickle.load(f)
print("对象已通过Pickle反序列化恢复。")
print(loaded_user.introduce())  # 输出: 我是Alice,今年25岁。
2. 

JSON:跨语言的“数据普通话” json模块将对象转换为JSON(JavaScript Object Notation)格式的字符串。JSON是目前互联网上最主流的数据交换格式,具有极佳的可读性和跨语言兼容性(几乎所有编程语言都支持)。但其缺点是只支持基本的数据类型(如dict、list、str、int、float、bool、None),无法直接序列化自定义对象。
为了使用json模块序列化自定义类,我们需要手动建立“对象<->字典”的转换桥梁。通常是在类中实现to_dict()方法用于序列化,以及from_dict()类方法用于反序列化。
以下代码演示了如何通过自定义转换方法,实现User类与JSON格式的互转。
代码
import json

class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    # 序列化:将对象转换为字典
    def to_dict(self):
        return {
            "name": self.name,
            "age": self.age
        }
    
    # 反序列化:从字典创建对象
    @classmethod
    def from_dict(cls, data):
        return cls(data["name"], data["age"])

# 1. 创建对象
user = User("Bob", 30)

# 2. 序列化:对象 -> 字典 -> JSON字符串 -> 文件
with open("user.json", "w", encoding="utf-8") as f:
    json.dump(user.to_dict(), f, ensure_ascii=False, indent=2)
print("对象已通过JSON序列化并保存。")

# 3. 反序列化:文件 -> JSON字符串 -> 字典 -> 对象
with open("user.json", "r", encoding="utf-8") as f:
    data = json.load(f)
    loaded_user = User.from_dict(data)
print("对象已通过JSON反序列化恢复。")
print(f"恢复的对象:{loaded_user.name}, {loaded_user.age}")
三、序列化方案选型对比
为了帮助你做出最佳选择,下表总结了picklejson的核心差异:
特性
Pickle
JSON
格式
二进制
文本(字符串)
可读性
不可读(乱码)
人类可读,结构清晰
跨语言
仅限Python
几乎所有编程语言都支持
支持类型
几乎所有Python对象
基础类型(dict, list, str等)
安全性
(反序列化可能执行恶意代码)
典型场景
Python内部对象存储、模型持久化
Web API、配置文件、跨平台通信
四、避坑指南与最佳实践
在使用序列化技术时,有几个关键点需要特别注意:
1. 

安全第一:警惕Pickle的反序列化风险 pickle模块在反序列化时,如果数据来自不可信的来源,可能会执行任意的恶意代码,从而导致严重的安全漏洞。因此,永远不要反序列化你无法确认来源的数据。在需要处理外部数据的场景(如网络API),应优先选择json
2. 

类定义的可访问性 使用pickle反序列化一个自定义类的实例时,Python需要能够找到该类的定义。如果序列化和反序列化的代码在不同的文件中,或者类的定义发生了改变(如方法被删除),反序列化可能会失败并抛出AttributeError。确保在反序列化之前,类的定义已经存在于当前的命名空间中。
3. 

文件打开模式 使用pickle读写文件时,必须使用二进制模式('wb'写,'rb'读)。而使用json时,则应使用文本模式('w'写,'r'读),并建议指定encoding='utf-8'以支持中文等非ASCII字符。
4. 

版本兼容性 pickle生成的文件通常与特定版本的Python绑定,不同版本的Python之间可能存在兼容性问题。如果需要长期存储数据,建议使用json或Protocol Buffers(Protobuf)等更具版本弹性的格式。
五、结语
掌握序列化与反序列化是Python开发者的必备技能。pickle以其强大的通用性,成为Python内部对象持久化的首选;而json则凭借其跨语言和高安全性,统治了Web数据交互的领域。在实际项目中,你可以根据具体需求——是纯粹的Python内部通信,还是需要与外部系统交互——来灵活选择最合适的工具。希望本文能帮助你彻底理解并熟练运用这两种技术。

购买须知/免责声明
1.本文部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责。
2.若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
3.如果本站有侵犯、不妥之处的资源,请在网站右边客服联系我们。将会第一时间解决!
4.本站所有内容均由互联网收集整理、网友上传,仅供大家参考、学习,不存在任何商业目的与商业用途。
5.本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
6.不保证任何源码框架的完整性。
7.侵权联系邮箱:aliyun6168@gail.com / aliyun666888@gail.com
8.若您最终确认购买,则视为您100%认同并接受以上所述全部内容。

免费源码网 Python Python对象序列化与反序列化:从入门到实战 https://svipm.com.cn/21223.html

相关文章

猜你喜欢