Python的pickle模块

        pickle 是 Python 标准库中的一个模块,用于对象的序列化(serialization)和反序列化(deserialization)。
        序列化是将对象转换为字节流的过程,而反序列化则是从字节流恢复对象的过程。
        通过 pickle 模块,可以将 Python 对象保存到文件中,或者通过网络传输,以及存储在数据库中。
主要功能
        序列化(dump):将 Python 对象转换为字节流并保存到文件或其它存储介质中。
        反序列化(load):从字节流中读取并重建原始的 Python 对象。
常用函数
        pickle.dump(obj, file, protocol=None):将对象 obj 序列化并写入到文件 file 中。file 需要是以二进制模式打开的文件对象,例如 open('file.pkl', 'wb')。protocol 是序列化协议的版本,可以选择不同的协议以优化性能或兼容性。
        pickle.load(file):从以二进制模式打开的文件 file 中读取并反序列化对象。例如 open('file.pkl', 'rb')。
        pickle.dumps(obj):将对象 obj 序列化为字节对象(bytes),而不是写入文件。
        pickle.loads(bytes_object):从字节对象(bytes)中反序列化并重建对象。
示例
序列化与反序列化到文件:

import pickle

# 假设有一个要保存的 Python 对象
data = {"name": "张三", "age": 30, "city": "上海"}

# 将对象保存到文件
with open("data.pkl", "wb") as file:
    pickle.dump(data, file)

# 从文件中读取对象
with open("data.pkl", "rb") as file:
    loaded_data = pickle.load(file)

print(loaded_data)  # 输出: {'name': '张三', 'age': 30, 'city': '上海'}

 序列化与反序列化到字节对象:

import pickle

# 假设有一个要保存的 Python 对象
data = ["苹果", "香蕉", "梨"]

# 将对象序列化为字节对象
serialized_data = pickle.dumps(data)

# 从字节对象中反序列化
deserialized_data = pickle.loads(serialized_data)

print(deserialized_data)  # 输出: ['苹果', '香蕉', '梨']

将保持目录结构的文件夹序列化到字节对象以及反操作:

import os
import pickle


# 序列化文件夹到文件
def serialize_files_in_directory_with_paths(directory, output_file):
    serialized_data = []

    for root, dirs, files in os.walk(directory):
        for file in files:
            file_path = os.path.join(root, file)
            try:
                with open(file_path, 'rb') as f:
                    file_content = f.read()
                serialized_content = pickle.dumps((file_path, file_content))
                serialized_data.append(serialized_content)
            except Exception as e:
                print(f"无法序列化文件 {file_path}: {e}")

    with open(output_file, 'wb') as f:
        for data in serialized_data:
            f.write(data)


# 反序列化文件到文件夹
def deserialize_files_from_file_with_paths(byte_stream_file, output_directory):
    if not os.path.exists(output_directory):
        os.makedirs(output_directory)

    with open(byte_stream_file, 'rb') as f:
        serialized_data = f.read()

    offset = 0
    while offset < len(serialized_data):
        try:
            file_path, file_content = pickle.loads(serialized_data[offset:])
            offset += len(pickle.dumps((file_path, file_content)))
            file_dir = os.path.dirname(file_path)
            if not os.path.exists(file_dir):
                os.makedirs(file_dir)
            with open(file_path, 'wb') as output_file:
                output_file.write(file_content)
        except Exception as e:
            print(f"无法反序列化字节流: {e}")
            break

# 序列化使用示例
directory_path = 'D:\\需要序列化的目录\\需要序列化的目录多层结构'   # 需要序列化的目录,比如位于D:\
output_file_path = 'path/to/output/file.pkl'
serialize_files_in_directory_with_paths(directory_path, output_file_path)



# 反序列化使用示例
byte_stream_file_path = 'file.pkl'
output_directory_path = 'D:\\'   # 反序列化后的文件保存的目录,必须是D:\的根目录,否则会反序列化失败
deserialize_files_from_file_with_paths(byte_stream_file_path, output_directory_path)

注意事项
        安全性:由于 pickle 可以执行反序列化过程中的任意代码,因此从不可信来源加载 pickle 数据可能会带来安全风险。攻击者可以通过恶意构造的 pickle 数据执行任意代码。因此,除非数据来源可信,否则不要轻易使用 pickle.load 或 pickle.loads。
        版本兼容性:不同版本的 Python 可能对 pickle 的协议有不同的支持。高版本的 Python 通常支持低版本的协议,但反之不一定成立。因此,在跨 Python 版本使用 pickle 数据时,需要注意协议的兼容性。
        不可移植性:pickle 数据是特定于 Python 的,因此不能在非 Python 环境中直接使用。如果需要跨语言的序列化方式,可以考虑使用 JSON、XML 或 MessagePack 等。
        性能:在某些情况下,pickle 的性能可能不是最佳选择,尤其是对于非常大的对象。可以考虑使用其他序列化库,如 json(适用于简单数据结构)或 msgpack(更高效的二进制格式)。
常见用途
        持久化存储:将 Python 对象保存到磁盘,以便稍后继续使用。
        缓存:将计算结果缓存到文件中,避免重复计算。
        数据传输:在 Python 程序之间或通过网络传输对象。一个典型应用是CIFAR10数据集,CIFAR10数据集的训练集有50000个图像文件,如果在操作系统中使用直接读写的方式移动这50000个文件,就意味着要执行50000次文件的读和写,效率很低。下图就是一次复制粘贴实测:

虽然所有文件只有大约120M大小,用了12分钟才完成。 

使用上面的代码将所有文件转换成一个字节流文件:

得到的字节流文件:

 对这个120M的单个文件的读写瞬间就可以完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深蓝海拓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值