当前位置: 首页 > news >正文

知识拓展:Python序列化模块pickle 模块详解

Python pickle 模块学习笔记

在这里插入图片描述

1. 简介

pickle 是 Python 的标准序列化模块,用于将 Python 对象转换为字节流(序列化)以及将字节流恢复为对象(反序列化)。它支持几乎所有的 Python 数据类型和对象。

官方文档:https://docs.python.org/zh-cn/3/library/pickle.html
序列化模块:marshal详解

2. 核心方法

pickle 模块提供了四个主要方法:

  1. pickle.dump(obj, file)

    • 将对象序列化并写入文件
    • 需要以二进制写入模式打开文件(‘wb’)
    # 示例:序列化基本数据类型到文件
    basic_data = {
        'int': 42,
        'float': 3.14,
        'str': 'Hello Pickle',
        'list': [1, 2, 3],
        'dict': {'a': 1, 'b': 2},
        'tuple': (4, 5, 6),
        'bool': True,
        'none': None
    }
    with open('basic_data.pkl', 'wb') as f:
        pickle.dump(basic_data, f)
    
  2. pickle.load(file)

    • 从文件中读取并反序列化为对象
    • 需要以二进制读取模式打开文件(‘rb’)
    # 示例:从文件中读取序列化的数据
    with open('basic_data.pkl', 'rb') as f:
        loaded_data = pickle.load(f)
    print("读取的数据:", loaded_data)
    
  3. pickle.dumps(obj)

    • 将对象序列化为字节串
    • 返回 bytes 类型数据
    # 示例:将数据序列化为字节串
    bytes_data = pickle.dumps(basic_data)
    print("序列化后的字节串类型:", type(bytes_data))
    print("字节串长度:", len(bytes_data))
    
  4. pickle.loads(bytes)

    • 将字节串反序列化为对象
    • 接收 bytes 类型数据
    # 示例:从字节串恢复数据
    recovered_data = pickle.loads(bytes_data)
    print("恢复的数据:", recovered_data)
    

3. 支持的数据类型

3.1 基本数据类型示例

basic_data = {
    'int': 42,                    # 整数
    'float': 3.14,               # 浮点数
    'str': 'Hello Pickle',       # 字符串
    'list': [1, 2, 3],          # 列表
    'dict': {'a': 1, 'b': 2},   # 字典
    'tuple': (4, 5, 6),         # 元组
    'bool': True,               # 布尔值
    'none': None                # None值
}

3.2 高级数据类型示例

import datetime

# 自定义类示例
class Person:
    def __init__(self, name, age, birthday):
        self.name = name
        self.age = age
        self.birthday = birthday
        self._private_attr = "这是私有属性"
    
    def greet(self):
        return f"Hello, I'm {self.name}!"

# 创建实例并序列化
person = Person("张三", 25, datetime.datetime(1998, 5, 15))
with open('person.pkl', 'wb') as f:
    pickle.dump(person, f)

# 反序列化并访问对象方法
with open('person.pkl', 'rb') as f:
    loaded_person = pickle.load(f)
print(f"姓名: {loaded_person.name}")
print(f"年龄: {loaded_person.age}")
print(f"生日: {loaded_person.birthday}")
print(f"问候语: {loaded_person.greet()}")

4. 协议版本

pickle 支持不同的协议版本,每个版本都有其特点:

# 协议版本示例
data = {"name": "李四", "age": 30}

# 测试不同协议版本
for protocol in range(6):  # 0-5 协议版本
    bytes_data = pickle.dumps(data, protocol=protocol)
    print(f"协议版本 {protocol} 序列化后的字节长度:", len(bytes_data))

协议版本特点:

  • 协议 0:ASCII 协议,人类可读,兼容旧版本
  • 协议 1:老式二进制协议,比协议 0 更高效
  • 协议 2:支持新式类,添加了对象引用支持
  • 协议 3:支持 bytes 对象,Python 3.x 的默认协议
  • 协议 4:支持大对象,更高效的序列化
  • 协议 5:支持带外数据和更快的序列化

5. 高级特性

5.1 序列化多个对象示例

# 序列化多个不同类型的对象
obj1 = ["apple", "banana", "orange"]
obj2 = {"x": 100, "y": 200}
obj3 = datetime.datetime.now()

# 写入多个对象
with open('multiple_objects.pkl', 'wb') as f:
    pickle.dump(obj1, f)
    pickle.dump(obj2, f)
    pickle.dump(obj3, f)

# 读取多个对象
with open('multiple_objects.pkl', 'rb') as f:
    loaded_obj1 = pickle.load(f)
    loaded_obj2 = pickle.load(f)
    loaded_obj3 = pickle.load(f)

print("列表对象:", loaded_obj1)
print("字典对象:", loaded_obj2)
print("日期对象:", loaded_obj3)

5.2 异常处理示例

# 文件不存在的异常处理
try:
    with open('not_exists.pkl', 'rb') as f:
        data = pickle.load(f)
except FileNotFoundError:
    print("文件不存在错误被捕获")

# 损坏数据的异常处理
try:
    pickle.loads(b'invalid data')
except pickle.UnpicklingError:
    print("反序列化错误被捕获")

6. 安全注意事项

  1. 安全风险

    • pickle 数据可能包含恶意代码
    • 永远不要 unpickle 不信任来源的数据
    • pickle 数据可能执行任意代码
  2. 最佳实践

    • 只处理可信来源的 pickle 数据
    • 考虑使用 JSON 等更安全的格式
    • 实现数据验证机制

7. 使用场景

适合使用 pickle 的场景:

  • 在 Python 程序间传递复杂数据结构
  • 保存程序状态
  • 缓存计算结果
  • 实现对象持久化
  • 序列化自定义类实例

不适合使用 pickle 的场景:

  • 需要跨语言交互
  • 处理不信任的数据
  • 需要长期存储(因版本兼容性问题)
  • 需要手动编辑序列化数据

8. 与其他序列化方案对比

  1. JSON

    • 优点:跨语言、可读性好、安全
    • 缺点:只支持基本数据类型
    • 使用场景:Web API、配置文件
  2. Marshal

    • 优点:更快、更轻量
    • 缺点:功能受限
    • 使用场景:Python 内部序列化
  3. YAML

    • 优点:可读性最好、配置文件友好
    • 缺点:速度较慢
    • 使用场景:配置文件、数据交换

9. 最佳实践

  1. 文件操作

    # 推荐使用 with 语句处理文件
    with open('data.pkl', 'wb') as f:
        pickle.dump(data, f)
    
  2. 性能优化

    # 使用最新协议版本获得最佳性能
    pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
    
  3. 错误处理

    try:
        with open('data.pkl', 'rb') as f:
            data = pickle.load(f)
    except (pickle.UnpicklingError, AttributeError, EOFError, ImportError) as e:
        print(f"反序列化错误: {e}")
    except FileNotFoundError:
        print("文件不存在")
    
  4. 安全建议

    • 实现数据验证机制
    • 限制反序列化时的资源使用
    • 考虑使用 copyreg 注册安全的类型
    • 在处理不信任数据时使用 JSON 替代
http://www.dtcms.com/a/16791.html

相关文章:

  • 牛客面筋学习
  • 鸿蒙开发:了解@Builder装饰器
  • mysql监控--慢查询
  • Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现一次触发控制三个光源开关分别采集三张图像(C#)
  • 深度学习入门:搭建你的第一个神经网络
  • 机器学习-02-机器学习算法思想以及在各行各业的应用
  • LINUX——基础指令
  • linux软件编程
  • 同创永益IT应急管理平台与Deepseek深度融合,开启智能应急新时代
  • 网络安全学习架构 网络安全架构内容
  • 地图打包注意事项
  • 如何使用 DeepSeek R1 构建开源 ChatGPT Operator 替代方案
  • DeepSeek-VL2 环境配置与使用指南
  • Sass更新:@import——>@use
  • 硬件-电源-隔离与非隔离的区别
  • Mac配置Flutter开发环境
  • 腾讯云Windows系统搭建ftp服务器上传图片
  • elementUI表单校验失败自动聚焦到失败input/select等输入框
  • 嵌入式硬件篇---OpenMV的硬件流和软件流
  • Ansible 自动化 Linux 运维:解放你的双手,让运维变得简单
  • Java进阶:Dubbo
  • C语言-结构体
  • Python爬虫-猫眼电影的影院数据
  • 【后端发展路径】基础技术栈、工程能力进阶、高阶方向、职业发展路径
  • oracle 19c安装DBRU补丁时报错CheckSystemSpace的处理
  • AI在网络安全中的应用:构建智能防护体系
  • 如果网络中断,Promise.race 如何处理?
  • 48. c++线程
  • Linux-文件基本操作1
  • 空间复杂度O(m) O(n) O是什么,m是什么,n是什么