0

0

Python 对象序列化与反序列化原理

冰川箭仙

冰川箭仙

发布时间:2026-01-31 16:34:58

|

513人浏览过

|

来源于php中文网

原创

pickle反序列化会执行任意代码,因其本质是记录并重放对象重建的构造指令流,攻击者可通过控制输入注入__reduce__恶意调用;它本就只应限于可信环境使用。

python 对象序列化与反序列化原理

为什么 pickle 反序列化会执行任意代码

pickle 不是数据格式协议,而是一套 Python 对象的“运行时快照”机制。它序列化时记录的是对象类型、属性值、以及重建该对象所需的**构造指令流**(类似字节码),反序列化时直接在当前解释器中执行这些指令。

这意味着只要攻击者能控制输入字节流,就能注入 __reduce__ 方法返回恶意函数调用,比如 os.systemeval。这不是 bug,而是设计使然——pickle 本就只应在可信环境中使用。

  • 永远不要用 pickle.load() 解析来自网络、文件或用户输入的未知数据
  • 替代方案:用 json(仅支持基础类型)、dataclasses.asdict() + json、或 msgpack(需显式注册类)
  • 若必须用 pickle,可用自定义 Unpickler 重写 find_class,白名单限制可加载的模块和类

json 序列化失败常见原因与绕过方式

json.dumps() 默认只接受 strintfloatboolNonelistdict 这七种类型。遇到 datetimebytes、自定义类实例时直接报 TypeError: Object of type ... is not JSON serializable

解决核心思路是提前把非标量对象“降维”成 JSON 可表示的结构:

立即学习Python免费学习笔记(深入)”;

JSON.NET 简单的使用 中文WORD版
JSON.NET 简单的使用 中文WORD版

本文档主要讲述的是JSON.NET 简单的使用;JSON.NET使用来将.NET中的对象转换为JSON字符串(序列化),或者将JSON字符串转换为.NET中已有类型的对象(反序列化?)。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

下载
  • default 参数传入转换函数,例如处理 datetimelambda obj: obj.isoformat() if isinstance(obj, datetime) else None
  • bytes,先 obj.decode('utf-8')(确保是文本)或 base64.b64encode(obj).decode('ascii')
  • 避免重写 JSONEncoder 子类——除非需要复用或统一规则;临时场景用 default 更轻量
  • 注意:json 不保留类型信息,反序列化后得靠业务逻辑手动还原为 datetime 等对象

自定义类如何支持 __getstate____setstate__

默认情况下,pickle 保存对象的整个 __dict__。但有些字段不该存(如打开的文件句柄、缓存、线程锁),有些字段需要特殊重建逻辑(如重建数据库连接)。

这时要显式定义 __getstate__(决定序列化哪些内容)和 __setstate__(决定反序列化时如何初始化):

def __getstate__(self):
    state = self.__dict__.copy()
    # 排除不可序列化的字段
    state.pop('cache', None)
    state.pop('_db_conn', None)
    return state

def setstate(self, state): self.dict.update(state)

手动重建资源

self._db_conn = self._connect_db()
  • __getstate__ 必须返回一个 pickleable 对象(通常是 dict)
  • __setstate__ 接收的就是这个对象,不一定要调用 __dict__.update,也可完全重新构造
  • 如果类有 __slots____dict__ 不存在,需改用 getattr(self, attr) 显式提取字段

不同序列化方式的性能与兼容性取舍

没有“最好”的序列化方式,只有“更适合当前场景”的选择。关键权衡点是:语言互通性 vs Python 特性支持 vs 体积 vs 速度。

  • pickle:最快、支持所有 Python 类型和引用关系,但仅限 Python,且不安全;适合进程内缓存或可信 RPC
  • json:跨语言、人可读、安全,但丢精度(如 int/float 混淆、无 datetime 原生支持)、体积大;适合 API 响应、配置文件
  • msgpack:二进制、比 JSON 小且快,支持扩展类型(需注册),但默认不支持 Python 特有对象;适合微服务间高效通信
  • pydantic.BaseModel.model_dump_json():自动处理嵌套模型 + datetime + enum,但依赖 pydantic,生成的是 JSON 字符串;适合现代 Python Web 后端

真正容易被忽略的是引用循环和共享对象——pickle 能正确处理,json 直接报错,msgpack 默认也不支持;如果数据结构里有 a.x = b; b.y = a 这种,得提前检测或扁平化。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

420

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

536

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

313

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

77

2025.09.10

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

580

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

103

2025.10.23

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

783

2023.08.22

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

783

2023.08.22

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

54

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号