4.5 Python3 pickle模块

部署运行你感兴趣的模型镜像

pickle 是 Python 的一个强大序列化模块,它可以将几乎任何 Python 对象转换为字节流(序列化),也可以从字节流重新构造对象(反序列化)


目录

1. 基本用法

1.1 序列化对象(pickling)

1.2 反序列化对象(unpickling)

2. 可序列化的对象类型

3. 高级特性

3.1 自定义类的序列化

3.2 序列化协议版本

4. 安全注意事项

5. 特殊方法控制序列化

6. 性能优化

7. 实际应用场景

1. 缓存计算结果

2. 进程间通信

8. 替代方案比较

总结


1. 基本用法

1.1 序列化对象(pickling)

import pickle

data = {
    'name': 'Alice',
    'age': 30,
    'scores': [85, 92, 88],
    'is_active': True
}

# 序列化到字节对象
serialized = pickle.dumps(data)
print(serialized)  # 输出字节序列

# 序列化到文件
with open('data.pkl', 'wb') as f:  # 注意是二进制写入模式
    pickle.dump(data, f)

1.2 反序列化对象(unpickling)

import pickle

# 首先创建一个示例数据对象
data = {
    'name': 'Alice',
    'age': 30,
    'scores': [85, 92, 88],
    'is_active': True
}

# 1. 序列化对象到字节(创建serialized变量)
serialized = pickle.dumps(data)
print("序列化后的字节数据:", serialized)

# 2. 从字节对象反序列化
deserialized = pickle.loads(serialized)
print("反序列化后的数据:", deserialized)  # 输出原始数据

# 3. 序列化到文件
with open('data.pkl', 'wb') as f:  # 注意是二进制写入模式
    pickle.dump(data, f)

# 4. 从文件反序列化
with open('data.pkl', 'rb') as f:  # 注意是二进制读取模式
    loaded_data = pickle.load(f)
    print("从文件加载的数据:", loaded_data)

2. 可序列化的对象类型

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

  • 基本数据类型(int, float, bool, str 等)

  • 容器类型(list, tuple, dict, set)

  • 函数和类(只序列化名称,不序列化代码)

  • 类的实例(包括自定义类)

  • 模块级函数和类


3. 高级特性

3.1 自定义类的序列化

import pickle

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

alice = Person('Alice', 30)

# 序列化自定义类实例
with open('person.pkl', 'wb') as f:
    pickle.dump(alice, f)

# 反序列化
with open('person.pkl', 'rb') as f:
    loaded_person = pickle.load(f)
    print(loaded_person)  # Person(name='Alice', age=30)

3.2 序列化协议版本

pickle 有多个协议版本,可以通过 protocol 参数指定:

# 使用最高效的协议版本(Python 3.8+默认使用协议4)
pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)

# 可用的协议版本:
# 0 - 原始ASCII协议(兼容旧版本)
# 1 - 旧二进制格式
# 2 - Python 2.3引入
# 3 - Python 3.0引入(默认Python 3.0-3.7)
# 4 - Python 3.4引入(默认Python 3.8+)
# 5 - Python 3.8引入(支持带外数据)
 

4. 安全注意事项

⚠️ 重要警告:pickle 反序列化可以执行任意代码,永远不要反序列化不受信任来源的数据

# 不安全的做法(可能执行恶意代码)
malicious_data = b"cos\nsystem\n(S'rm -rf /'\ntR."  # 模拟恶意pickle数据
# pickle.loads(malicious_data)  # 危险!会执行系统命令

安全替代方案:

  • 对于不受信任的数据,使用 json 模块

  • 或者使用 ast.literal_eval() 处理简单数据结构


5. 特殊方法控制序列化

自定义类可以通过实现特殊方法来控制序列化行为:

import pickle

class CustomObject:
    def __init__(self, value):
        self.value = value
        self._internal = "secret"
    
    # 定义序列化时要保存的属性
    def __getstate__(self):
        state = self.__dict__.copy()
        del state['_internal']  # 不序列化内部属性
        return state
    
    # 定义反序列化时的行为
    def __setstate__(self, state):
        self.__dict__.update(state)
        self._internal = "restored"  # 恢复时重新设置

obj = CustomObject(42)
serialized = pickle.dumps(obj)
new_obj = pickle.loads(serialized)
print(new_obj.value)  # 42
print(new_obj._internal)  # "restored"

6. 性能优化

对于大型对象的序列化:

# 使用更高效的协议
data = [i**2 for i in range(100000)]

# 比较不同协议的大小
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
    size = len(pickle.dumps(data, protocol=proto))
    print(f"协议 {proto}: {size} 字节")

# 使用更快的pickle实现(需要安装)
# pip install pickle5  # 对于Python < 3.8想使用协议5

7. 实际应用场景

7.1 缓存计算结果

import pickle
import hashlib
import os

def compute_expensive_operation(params):
    cache_file = f"cache_{hashlib.md5(str(params).encode()).hexdigest()}.pkl"
    
    if os.path.exists(cache_file):
        with open(cache_file, 'rb') as f:
            return pickle.load(f)
    
    # 模拟耗时计算
    result = sum(x**2 for x in range(params['n']))
    
    # 缓存结果
    with open(cache_file, 'wb') as f:
        pickle.dump(result, f)
    
    return result

7.2 进程间通信

import pickle
from multiprocessing import Pool

# 在多进程中使用pickle传递数据

def process_data(data):
    # 处理数据...
    return data * 2

if __name__ == '__main__':
    data = [1, 2, 3, 4, 5]
    with Pool() as pool:
        results = pool.map(process_data, data)
    print(results)  # [2, 4, 6, 8, 10]

8. 替代方案比较

特性picklejsonmarshalshelve
人类可读
跨语言支持
序列化复杂对象⚠️
安全性
内置支持

总结

pickle 是 Python 中最强大的序列化工具,适合:

  • 需要保存 Python 特有对象(如自定义类实例)

  • 临时存储 Python 数据

  • 进程间传递复杂对象

但需要注意:

  1. 永远不要反序列化不受信任的数据

  2. pickle 文件不能跨 Python 版本/实现(如 CPython 和 PyIron)兼容

  3. 对于长期存储或跨语言场景,考虑使用 JSON 或其他格式


您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值