菜鸟教程 -- 学的不仅是技术,更是梦想!

Python 3 教程
Python3 教程 Python3 简介 Python3 环境搭建 Python3 VScode Python3 基础语法 Python3 基本数据类型 Python3 数据类型转换 Python3 解释器 Python3 注释 Python3 运算符 Python3 数字(Number) Python3 字符串 Python3 列表 Python3 元组 Python3 字典 Python3 集合 Python3 条件控制 Python3 循环语句 Python3 编程第一步 Python3 推导式 Python3 迭代器与生成器 Python3 with Python3 函数 Python3 lambda Python3 装饰器 Python3 数据结构 Python3 模块 Python __name__ Python3 输入和输出 Python3 File Python3 OS Python3 错误和异常 Python3 面向对象 Python3 命名空间/作用域 Python 虚拟环境的创建 Python 类型注解 Python3 标准库概览 Python3 实例 Python 测验

Python3 高级教程

Python3 正则表达式 Python3 CGI编程 Python3 MySQL(mysql-connector) Python3 MySQL(PyMySQL) Python3 网络编程 Python3 SMTP发送邮件 Python3 多线程 Python3 XML 解析 Python3 JSON Python3 日期和时间 Python3 内置函数 Python3 MongoDB Python3 urllib Python uWSGI 安装配置 Python3 pip Python3 operator Python math Python requests Python random Python OpenAI Python 有用的资源 Python AI 绘画 Python statistics Python hashlib Python 量化 Python pyecharts Python selenium 库 Python 爬虫 Python Scrapy 库 Python Markdown Python sys 模块 Python Pickle 模块 Python subprocess 模块 Python queue 模块 Python StringIO 模块 Python logging 模块 Python datetime 模块 Python re 模块 Python csv 模块 Python threading 模块 Python asyncio 模块 Python PyQt Python for 循环 Python while 循环
(追記) (追記ここまで)

Python Pickle 模块

在 Python 开发中,我们经常需要把运行时的对象保存下来,或者在程序重启后恢复之前的状态,例如:

  • 将计算结果缓存到磁盘,避免重复计算
  • 保存用户配置、程序中间状态
  • 在不同 Python 进程之间传递复杂对象

pickle 模块正是 Python 为解决这类问题提供的官方内置方案

Python 的 pickle 模块是一个用于序列化和反序列化 Python 对象的标准库模块。

在开始使用 Pickle 之前,需要理解两个核心概念:

  • 序列化(Pickling):将 Python 对象转换为字节序列
  • 反序列化(Unpickling):将字节序列转换回 Python 对象

pickle 模块可以将几乎所有的 Python 对象(如列表、字典、类实例等)保存到文件中,或者通过网络传输,然后在需要时重新加载。

为什么使用 Pickle 模块?

  1. 数据持久化:将 Python 对象保存到文件中,以便在程序关闭后仍然可以访问这些数据。
  2. 数据传输:通过网络传输 Python 对象,例如在分布式系统中传递数据。
  3. 快速存储和加载:pickle 模块可以高效地处理复杂的数据结构,适合需要快速存储和加载的场景。

Pickle 的典型使用场景

pickle 非常适合以下场景:

  1. 本地数据持久化
  2. 程序运行状态保存与恢复
  3. 中间计算结果缓存
  4. Python 进程间通信(IPC)
  5. 机器学习模型、特征数据的保存

不适合的场景:

  • 跨语言数据交换
  • 前后端接口数据传输
  • 不可信数据源的反序列化

Pickle 支持哪些对象?

1. 支持的对象类型

类型 是否支持
int / float / bool / str 支持
list / tuple / dict / set 支持
None 支持
自定义类实例 支持
嵌套结构 支持

不支持或不推荐的对象

  • 打开的文件对象
  • socket、数据库连接
  • 操作系统资源
  • 依赖运行环境状态的对象

导入模块

使用 Pickle 模块非常简单,只需要导入即可:

import pickle

Pickle 模块的基本用法

1. 序列化对象

使用 pickle.dump() 方法可以将 Python 对象序列化并保存到文件中。

实例

import pickle

# 创建一个 Python 对象
data = {
'name': 'Alice',
'age': 25,
'hobbies': ['reading', 'traveling']
}

# 将对象序列化并保存到文件
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
  • 'wb' 表示以二进制写模式打开文件。
  • pickle.dump()data 对象序列化并写入文件。

2. 反序列化对象

使用 pickle.load() 方法可以从文件中加载并反序列化 Python 对象。

实例

import pickle

# 从文件中加载并反序列化对象
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)

print(loaded_data)
  • 'rb' 表示以二进制读模式打开文件。
  • pickle.load() 从文件中读取字节流并反序列化为 Python 对象。

3.序列化到字节串

如果不想保存到文件,可以使用 pickle.dumps() 将对象序列化为字节串:

实例

import pickle

data = [1, 2, 3, 4, 5]

# 序列化为字节串
byte_data = pickle.dumps(data)
print(byte_data)
# 输出类似: b'\x80\x04\x95\x0f\x00\x00\x00...'

4. 从字节串反序列化

使用 pickle.loads() 可以从字节串反序列化对象:

实例

import pickle

byte_data = b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03K\x04K\x05e.'

# 从字节串反序列化
original_data = pickle.loads(byte_data)
print(original_data)
# 输出: [1, 2, 3, 4, 5]

5. 可以序列化的对象类型

Pickle 可以序列化大多数 Python 对象,包括:

  • 基本数据类型:整数、浮点数、字符串、布尔值、None
  • 集合类型:列表、元组、字典、集合
  • 自定义类的实例
  • 函数和类(有一定限制)

实例

import pickle

# 序列化不同类型的数据
numbers = [1, 2, 3]
text = "Hello, Pickle"
dictionary = {'key': 'value'}
tuple_data = (1, 2, 3)
set_data = {1, 2, 3}

# 将所有数据放入一个列表
all_data = [numbers, text, dictionary, tuple_data, set_data]

# 序列化
with open('mixed_data.pkl', 'wb') as f:
pickle.dump(all_data, f)

# 反序列化
with open('mixed_data.pkl', 'rb') as f:
loaded_data = pickle.load(f)
print(loaded_data)

6. 序列化自定义类

Pickle 可以很好地处理自定义类的实例:

实例

import pickle

class Student:
def __init__(self, name, age, grade):
self.name = name
self.age = age
self.grade = grade

def __repr__(self):
return f"Student(name={self.name}, age={self.age}, grade={self.grade})"

# 创建实例
student = Student("李四", 20, "大三")

# 序列化
with open('student.pkl', 'wb') as f:
pickle.dump(student, f)

# 反序列化
with open('student.pkl', 'rb') as f:
loaded_student = pickle.load(f)
print(loaded_student)
# 输出: Student(name=李四, age=20, grade=大三)

7. 序列化多个对象

可以多次调用 pickle.dump() 来保存多个对象:

实例

import pickle

data1 = {'item': 'apple', 'count': 5}
data2 = ['banana', 'orange', 'grape']
data3 = 42

# 保存多个对象
with open('multiple.pkl', 'wb') as f:
pickle.dump(data1, f)
pickle.dump(data2, f)
pickle.dump(data3, f)

# 读取多个对象(顺序必须一致)
with open('multiple.pkl', 'rb') as f:
loaded_data1 = pickle.load(f)
loaded_data2 = pickle.load(f)
loaded_data3 = pickle.load(f)

print(loaded_data1)
print(loaded_data2)
print(loaded_data3)

8. 实际应用示例

示例1:保存和加载机器学习模型配置

实例

import pickle

# 模拟机器学习模型的配置
model_config = {
'model_type': 'RandomForest',
'n_estimators': 100,
'max_depth': 10,
'trained_date': '2024-01-13',
'accuracy': 0.95
}

# 保存配置
with open('model_config.pkl', 'wb') as f:
pickle.dump(model_config, f)

# 加载配置
with open('model_config.pkl', 'rb') as f:
config = pickle.load(f)
print(f"模型类型: {config['model_type']}")
print(f"准确率: {config['accuracy']}")

示例2:缓存计算结果

实例

import pickle
import os

def expensive_computation(n):
"""模拟耗时的计算"""
result = sum(i ** 2 for i in range(n))
return result

def compute_with_cache(n, cache_file='cache.pkl'):
# 检查缓存是否存在
if os.path.exists(cache_file):
with open(cache_file, 'rb') as f:
cache = pickle.load(f)
if n in cache:
print("从缓存中读取结果")
return cache[n]
else:
cache = {}

# 执行计算
print("执行计算...")
result = expensive_computation(n)

# 保存到缓存
cache[n] = result
with open(cache_file, 'wb') as f:
pickle.dump(cache, f)

return result

# 使用示例
print(compute_with_cache(1000000)) # 第一次会计算
print(compute_with_cache(1000000)) # 第二次从缓存读取

Pickle 模块的注意事项

  1. 安全性:pickle 模块在反序列化时会执行任意代码,因此不要加载来自不可信来源的 pickle 数据,以免遭受恶意攻击。
  2. 兼容性:pickle 生成的字节流是 Python 特有的,不同版本的 Python 之间可能存在兼容性问题。
  3. 性能:对于大型数据集,pickle 的序列化和反序列化可能会比较慢,可以考虑使用更高效的序列化工具,如 jsonmsgpack

高级用法:自定义对象的序列化

pickle 模块支持自定义类的序列化。默认情况下,pickle 会保存对象的属性和类名。如果需要更复杂的序列化逻辑,可以在类中实现 __getstate__()__setstate__() 方法。

实例

import pickle

class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def __getstate__(self):
# 自定义序列化逻辑
return {'name': self.name, 'age': self.age}

def __setstate__(self, state):
# 自定义反序列化逻辑
self.name = state['name']
self.age = state['age']

# 创建对象并序列化
person = Person('Bob', 30)
with open('person.pkl', 'wb') as file:
pickle.dump(person, file)

# 反序列化对象
with open('person.pkl', 'rb') as file:
loaded_person = pickle.load(file)

print(loaded_person.name, loaded_person.age)

pickle 模块常用方法

方法说明示例
pickle.dump(obj, file)将对象序列化并写入文件pickle.dump(data, open('data.pkl', 'wb'))
pickle.load(file)从文件读取并反序列化对象data = pickle.load(open('data.pkl', 'rb'))
pickle.dumps(obj)将对象序列化为字节串bytes_data = pickle.dumps([1, 2, 3])
pickle.loads(bytes)从字节串反序列化对象lst = pickle.loads(bytes_data)
pickle.HIGHEST_PROTOCOL可用的最高协议版本(属性)pickle.dump(..., protocol=pickle.HIGHEST_PROTOCOL)
pickle.DEFAULT_PROTOCOL默认协议版本(属性,通常为4)pickle.dumps(obj, protocol=pickle.DEFAULT_PROTOCOL)

1. 序列化对象到文件

实例

import pickle
data = {'name': 'Alice', 'age': 25}
with open('data.pkl', 'wb') as f:
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)

2. 从文件反序列化

实例

with open('data.pkl', 'rb') as f:
loaded_data = pickle.load(f)
print(loaded_data) # 输出: {'name': 'Alice', 'age': 25}

3. 序列化为字节串(网络传输/缓存)

实例

bytes_data = pickle.dumps([1, 2, 3], protocol=4)
restored_list = pickle.loads(bytes_data)

pickle 模块协议版本

协议版本说明
0人类可读的ASCII格式(兼容旧版)
1二进制格式(兼容旧版)
2Python 2.3+ 优化支持类对象
3Python 3.0+ 默认协议(不支持Python 2)
4Python 3.4+ 支持更大对象和更多数据类型
5Python 3.8+ 支持内存优化和数据共享
AI 思考中...

点我分享笔记

  • 昵称 (必填)
  • 邮箱 (必填)
  • 引用地址

AltStyle によって変換されたページ (->オリジナル) /