Pickle 的序列化与反序列化

  • 序列化 (Serialization):将 Python 物件转换为二进制格式,便于储存或传输。
  • 反序列化 (Deserialization):将二进制格式的资料还原为原本的 Python 物件。更多内容Python 序列化Serialization and 反序列化Deserialization

什么是 Pickle?

Pickle 是 Python 提供的一个内建模组,专门用于将 Python 物件序列化(serialize)和反序列化(deserialize)。它将 Python 物件转换为二进制格式,便于储存到档案或传输到网路上,并且能够随时还原成原始的 Python 物件。

Pickle 的主要用途

  • 储存 Python 物件到档案:将变数(如列表、字典、类别等)储存到磁盘,以便在未来的程式执行中重复使用。
  • 物件的网路传输:将 Python 物件序列化后,可以透过网路传输并在接收端反序列化还原。
  • 保存程式状态:在某些情况下,可以用来保存程式的中间状态,稍后继续执行。

如何使用 Pickle?

  • 汇入模组要使用 Pickle,首先要汇入 pickle 模组:
  • import pickle

  • 将资料序列化并储存到档案使用 pickle.dump() 方法,可以将 Python 物件序列化后储存在档案中:
  • # 要储存的物件
    data = {"name": "Alice", "age": 30, "languages": ["Python", "C++", "Java"]}

    # 打开档案,以二进制写入模式(wb)
    with open("data.pkl", "wb") as file:
    pickle.dump(data, file)

    print("资料已序列化并储存到档案 data.pkl")

  • 从档案中读取资料并反序列化使用 pickle.load() 方法,可以将储存的二进制格式资料反序列化为 Python 物件:
  • # 打开档案,以二进制读取模式(rb)
    with open("data.pkl", "rb") as file:
    loaded_data = pickle.load(file)

    print("从档案中还原的资料:", loaded_data)

    pickle常见情境:

  • 保存复杂的 Python 资料结构当资料结构包含像是列表、字典,甚至自订类别的物件,并且希望在稍后还原使用时,pickle 是一个快速且方便的工具。例如:
    • 中间处理结果的保存和读取(如数据分析中的数据快取)。
    • 机器学习中训练后的模型保存(如 scikit-learn 使用 pickle 保存模型)。
  • 程序之间的数据传递如果有多个 Python 程序需要共享数据,可以透过 pickle 序列化资料,将其储存到档案或传递到其他程序。例如:
    • 保存状态以供另一个程序读取。
    • 透过网路或管道传递序列化的物件。
  • 保存和还原工作进度如果程式执行需要很长时间,pickle 可用于保存执行的中间状态,避免重复执行相同的操作。例如:长时间运行的数据处理工作中保存进度,然后在程序崩溃或中断时还原。

  • 快速测试或临时保存在开发和测试中,pickle 可以用来临时保存数据以快速调试或测试功能。

  • 使用 pickle 的注意事项

    安全性问题:pickle 无法防范恶意数据,因此不要反序列化(pickle.load)不受信任的来源的数据。与 JSON 的选择:

    当数据只包含基本类型(如字典、列表、数字、字符串等)时,应优先使用 JSON,因为 JSON 可读性高且跨语言支持。若数据包含复杂 Python 特定结构(如自订类别或函数),可使用 pickle。

    什么时候不应该使用 pickle?

    • 需要跨语言操作:如果需要和非 Python 程序共享数据,应使用 JSON 或其他标準格式。
    • 需要数据长期保存:如果数据需要长期保存或存入资料库,pickle 并不是最佳选择,因为它受 Python 版本影响且可读性差。

    Shelve

    shelve 是 Python 标準库中一个方便的模组,用于将 Python 物件存储到一个类似字典的持久化对象中。它结合了 pickle 的序列化能力和简单的键值存取方式,使得开发者可以轻鬆地保存和读取 Python 的数据结构到文件中,而不需要自己处理文件操作和序列化细节。

    shelve 的特点

  • 类似字典的操作方式:
    • 用法和字典类似,可以透过键值对储存和读取数据。
    • 使用时只需记住操作字典的方法,例如 db[key] = value。
  • 自动序列化:
    • 支持将多种类型的 Python 物件(如字典、列表、自定义对象)直接保存到档案中,底层使用 pickle 处理序列化。
  • 持久化存储:
    • 数据保存在硬盘文件中,程序重启后仍能读取。
  • 效率较高:
    • 因为只在需要时加载数据,对于大数据集,比 JSON 或单一 pickle 文件更有效。
  • 限制:
    • 只能使用字符串作为键。
    • 存储的对象需可被 pickle 序列化。
    • 与数据库的设计不同,适用于简单数据存储而非高併发操作。
  • 基本使用范例

    import shelve

    # 开启一个 shelve 档案
    with shelve.open("mydata") as db:
    # 储存数据
    db["name"] = "Alice"
    db["age"] = 30
    db["skills"] = ["Python", "C++", "Java"]

    # 从档案中读取数据
    print(db["name"]) # 输出: Alice
    print(db["age"]) # 输出: 30
    print(db["skills"]) # 输出: [\'Python\', \'C++\', \'Java\']

    特性
    Shelve
    Pickle
    JSON
    SQLite
    储存格式 类似字典的档案 二进制档案 文本档案 数据库档案
    可读性
    数据类型支持 任意 Python 对象 任意 Python 对象 基本数据类型 基本数据类型
    操作方式 类似字典 程序控制序列化/反序列化 程序控制序列化/反序列化 SQL 操作
    应用场景 小型数据持久化存储 任意序列化需求 跨语言数据传输 结构化数据存储