百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Python内置模块pickle:Python 对象序列化详解

itomcoil 2025-09-13 01:13 1 浏览

1. 知识导图

2. 序列化与反序列化

2.1 定义与原理

序列化(Pickling)是将Python对象及其所拥有的层次结构转化为一个字节流的过程,而反序列化(Unpickling)是将字节流转化回一个对象层次结构的过程。

原理:pickle模块通过跟踪已被序列化的对象,避免了重复序列化,支持递归对象和共享对象。它还可以透明地存储并保存类实例。

2.2 示例

import pickle

# 序列化
data = {'a': [1, 2.0, 3+4j], 'b': ("character string", b"byte string"), 'c': {None, True, False}}
with open('data.pickle', 'wb') as f:
    pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)

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

3. 与其他模块的关系

3.1 与marshal模块的关系

pickle模块与marshal模块的主要区别在于pickle支持递归对象和共享对象,而marshal不支持。

表3.1 pickle与marshal模块对比

特性picklemarshal递归对象支持是否共享对象支持是否用户定义类支持是否跨版本兼容性是否

3.2 与json模块的比较

pickle是Python专用的二进制序列化格式,而json是文本序列化格式,广泛用于Python系统之外。

表3.2 pickle与json模块对比

特性picklejson序列化格式二进制文本可读性否是跨语言支持否是自定义类支持是否

4. 数据流格式

pickle模块使用Python专属的数据格式,支持多种协议版本,从v0到v5。

表4.1 pickle协议版本

协议版本特性兼容性v0人类可读所有Python版本v1二进制格式所有Python版本v2新式类支持Python 2.3+v3支持bytes对象Python 3.0-3.7v4大对象支持Python 3.4+v5带外数据支持Python 3.8+

5. 模块接口

5.1 主要函数

  • o pickle.dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)
  • o pickle.dumps(obj, protocol=None, *, fix_imports=True, buffer_callback=None)
  • o pickle.load(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)
  • o pickle.loads(data, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)

5.2 异常

  • o pickle.PickleError
  • o pickle.PicklingError
  • o pickle.UnpicklingError

6. 可以被封存/解封的对象

可以被封存的对象包括

  • o 内置常量 (None, True, False, Ellipsis, NotImplemented)
  • o 整数、浮点数、复数
  • o 字符串、字节串、字节数组
  • o 只包含可封存对象的元组、列表、集合和字典
  • o 可在模块最高层级上访问的函数和类
  • o 类的实例(仅限可封存的状态)

7. 封存类实例

7.1 特殊方法

  • o __getnewargs_ex__()
  • o __getnewargs__()
  • o __getstate__()
  • o __setstate__()
  • o __reduce__()
  • o __reduce_ex__()

7.2 示例

class TextReader:
    def __init__(self, filename):
        self.filename = filename
        self.file = open(filename)
        self.lineno = 0

    def readline(self):
        self.lineno += 1
        line = self.file.readline()
        if not line:
            return None
        if line.endswith('\n'):
            line = line[:-1]
        return "%i: %s" % (self.lineno, line)

    def __getstate__(self):
        state = self.__dict__.copy()
        del state['file']
        return state

    def __setstate__(self, state):
        self.__dict__.update(state)
        self.file = open(self.filename)
        for _ in range(self.lineno):
            self.file.readline()
        self.file = open(self.filename)

8. 持久化外部对象

8.1 示例

import pickle
import sqlite3
from collections import namedtuple

MemoRecord = namedtuple("MemoRecord", "key, task")

class DBPickler(pickle.Pickler):
    def persistent_id(self, obj):
        if isinstance(obj, MemoRecord):
            return ("MemoRecord", obj.key)
        return None

class DBUnpickler(pickle.Unpickler):
    def __init__(self, file, connection):
        super().__init__(file)
        self.connection = connection

    def persistent_load(self, pid):
        cursor = self.connection.cursor()
        type_tag, key_id = pid
        if type_tag == "MemoRecord":
            cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
            key, task = cursor.fetchone()
            return MemoRecord(key, task)
        raise pickle.UnpicklingError("unsupported persistent object")

9. Dispatch表

9.1 示例

import io
import pickle
import copyreg

f = io.BytesIO()
p = pickle.Pickler(f)
p.dispatch_table = copyreg.dispatch_table.copy()
p.dispatch_table[SomeClass] = reduce_SomeClass

10. 处理有状态的对象

10.1 示例

class TextReader:
    def __init__(self, filename):
        self.filename = filename
        self.file = open(filename)
        self.lineno = 0

    def readline(self):
        self.lineno += 1
        line = self.file.readline()
        if not line:
            return None
        if line.endswith('\n'):
            line = line[:-1]
        return "%i: %s" % (self.lineno, line)

    def __getstate__(self):
        state = self.__dict__.copy()
        del state['file']
        return state

    def __setstate__(self, state):
        self.__dict__.update(state)
        self.file = open(self.filename)
        for _ in range(self.lineno):
            self.file.readline()
        self.file = open(self.filename)

11. 类型,函数和其他对象的自定义归约

11.1 示例

import io
import pickle

class MyClass:
    my_attribute = 1

class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        if getattr(obj, "__name__", None) == "MyClass":
            return type, (obj.__name__, obj.__bases__, {'my_attribute': obj.my_attribute})
        return NotImplemented

f = io.BytesIO()
p = MyPickler(f)
p.dump(MyClass)

12. 外部缓冲区

12.1 示例

class ZeroCopyByteArray(bytearray):
    def __reduce_ex__(self, protocol):
        if protocol >= 5:
            return type(self)._reconstruct, (PickleBuffer(self),), None
        return type(self)._reconstruct, (bytearray(self),)

    @classmethod
    def _reconstruct(cls, obj):
        with memoryview(obj) as m:
            obj = m.obj
            if type(obj) is cls:
                return obj
            return cls(obj)

13. 限制全局变量

13.1 示例

import builtins
import io
import pickle

safe_builtins = {'range', 'complex', 'set', 'frozenset', 'slice'}

class RestrictedUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        if module == "builtins" and name in safe_builtins:
            return getattr(builtins, name)
        raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))

def restricted_loads(s):
    return RestrictedUnpickler(io.BytesIO(s)).load()

14. 性能

较新版本的pickle协议(第2版或更高)具有针对某些常见特性和内置类型的高效二进制编码格式。此外,pickle模块还拥有一个以C编写的透明优化器。

15. 学习总结

15.1 学习路线

  1. 1. 理解序列化与反序列化的基本概念
  2. 2. 掌握pickle模块的基本用法
  3. 3. 了解pickle与其他模块的区别
  4. 4. 学习pickle的数据流格式和协议版本
  5. 5. 掌握pickle模块的接口和异常处理
  6. 6. 学习如何封存和解封类实例
  7. 7. 了解持久化外部对象的方法
  8. 8. 学习Dispatch表的使用
  9. 9. 掌握处理有状态对象的方法
  10. 10. 学习自定义归约的方法
  11. 11. 了解外部缓冲区的使用
  12. 12. 学习限制全局变量的方法
  13. 13. 了解pickle的性能优化

15.2 学习总结

通过本教程,我们可以掌握Python内置模块pickle的基本用法和高级特性。pickle模块是Python中非常强大的工具,可以用于对象的序列化和反序列化,适用于多种应用场景。


持续更新Python编程学习日志与技巧,敬请关注!


#编程# #学习# #python# #在头条记录我的2025#

相关推荐

python数据分析中你必须知道的陷阱和技巧

数据分析是一门既有趣又有挑战的技能,它可以帮助我们从海量的数据中提取有价值的信息,为决策提供支持。但是,数据分析也不是一件轻松的事情,它需要我们掌握一定的编程、统计、可视化等知识,同时也要注意避免一些...

python常见五大坑及避坑指南_python解决什么问题

python是一门非常流行和强大的编程语言,但是也有一些容易让初学者或者不熟悉的人掉入的坑。这里列举了一些python常见五大坑,以及如何避免或者解决它们。缩进问题。python使用缩进来表示代码块,...

收藏!2022年国家职业资格考试时间表公布

人社部14日公布2022年度专业技术人员职业资格考试工作计划,包括中小学生教师资格、会计师、精算师、建造师等各项考试日期。其中,证券期货基金业从业人员资格各次考试地点不同,具体安排以相关行业协会考试公...

苹果mac系统必须安装python3_macbook安装python3.7

苹果mac系统必须安装python3苹果mac系统口碑很好,但不能像linux系统一样同时提供python2和python3环境,对程序员来说是非常不友善的。资深程序员都知道,Python3才是P...

通过python实现猴子吃桃问题_python小猴子吃桃的问题

1、问题描述:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,就只剩...

python 中的第一个 hello world 程序输出

程序运行:print("helloworld")我使用的是Python程序3.7.0版本介绍下print概念print字面意思打印,将文本输出内容打印出来输入:print(&...

持久化 Python 会话:实现数据持久化和可重用性

Midjourney生成R语言会话持久化熟悉或常用R语言进行数据分析/数据挖掘/数据建模的数据工作者可能对R语言的会话保存和会话恢复印象比较深刻,它可以将当前session会话持久化保存,以便分...

如何将Python算法模型注册成Spark UDF函数实现全景模型部署

背景Background对于算法业务团队来说,将训练好的模型部署成服务的业务场景是非常常见的。通常会应用于三个场景:部署到流式程序里,比如风控需要通过流式处理来实时监控。部署到批任务中部署成API服...

Python 字典l转换成 JSON_python转化字典

本文需要5分钟。如果对您有用可以点赞评论关注.Python字典到JSONJSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,它基于ECMAScrip...

[python] 基于PyOD库实现数据异常检测

PyOD是一个全面且易于使用的Python库,专门用于检测多变量数据中的异常点或离群点。异常点是指那些与大多数数据点显著不同的数据,它们可能表示错误、噪声或潜在的有趣现象。无论是处理小规模项目还是大型...

总结90条写Python程序的建议_python写程序的步骤

  1.首先  建议1、理解Pythonic概念—-详见Python中的《Python之禅》  建议2、编写Pythonic代码  (1)避免不规范代码,比如只用大小写区分变量、使用容易...

ptrade系列第六天:持久化处理2_持久化的三种状态

前一次跟大家分享了利用pickle进行策略数据的持久化。但是这种方式有个问题,就是保存下来的数据无法很直观的看到,比较不方便,所以今天给大家带来另一种方式,将数据通过json保存。importjso...

Python数据持久化:JSON_python的json用法

编程派微信号:codingpy上周更新的《ThinkPython2e》第14章讲述了几种数据持久化的方式,包括dbm、pickle等,但是考虑到篇幅和读者等因素,并没有将各种方式都列全。本文将介绍...

干货 | 如何利用Python处理JSON格式的数据,建议收藏

作者:俊欣来源:关于数据分析与可视化JSON数据格式在我们的日常工作中经常会接触到,无论是做爬虫开发还是一般的数据分析处理,今天,小编就来分享一下当数据接口是JSON格式时,如何进行数据处理进行详...

Python中Pyyaml模块的使用_python模块介绍

一、YAML是什么YAML是专门用来写配置文件的语言,远比JSON格式方便。YAML语言的设计目标,就是方便人类读写。YAML是一种比XML和JSON更轻的文件格式,也更简单更强大,它可以通过缩进来表...