首页 / Python3 入门教程 / 序列化

Python3 入门教程

序列化

本教程共 70 篇 · 第 47 篇 · 更新于 2026-07-22 · 约 6 分钟阅读

PythonPython3 入门教程序列化pickleJSONCSV

47. 序列化

本节目标:掌握 picklejsoncsv 三种数据持久化方式,理解各自的适用场景和安全性差异。

内存里的数据结构(列表、字典、对象)程序一关就消失。把它们转成可以存储或传输的格式,这个过程叫「序列化(serialization)」。反方向从存储格式恢复数据结构,叫「反序列化(deserialization)」。

Python 提供了多种序列化工具。这一章讲最常用的三种:picklejsoncsv

pickle:Python 对象的专用序列化

pickle 模块可以把几乎任何 Python 对象转成字节流,也能完全恢复:

import pickle

data = {'name': 'Alice', 'age': 25, 'scores': [85, 90, 88]}

# 序列化到文件
with open('data.pkl', 'wb') as f:
    pickle.dump(data, f)

# 从文件反序列化
with open('data.pkl', 'rb') as f:
    loaded = pickle.load(f)

print(loaded)  # {'name': 'Alice', 'age': 25, 'scores': [85, 90, 88]}

dumpload 操作文件对象,dumpsloads 操作内存中的 bytes

import pickle

blob = pickle.dumps(data)
print(type(blob))  # <class 'bytes'>

loaded = pickle.loads(blob)
print(loaded == data)  # True
Warning

pickle 绝对不要加载不可信来源的数据。恶意构造的 pickle 数据可以在反序列化时执行任意代码。只用来处理自己生成的文件,或者完全可信的内部数据交换。

JSON:跨语言的通用格式

JSON(JavaScript Object Notation)是 web 开发的事实标准。Python 的 json 模块支持它:

import json

data = {'name': 'Alice', 'age': 25, 'active': True}

# 序列化为 JSON 字符串
json_str = json.dumps(data, ensure_ascii=False)
print(json_str)  # {"name": "Alice", "age": 25, "active": true}

# 反序列化
loaded = json.loads(json_str)
print(loaded)  # {'name': 'Alice', 'age': 25, 'active': True}

ensure_ascii=False 让中文字符原样输出,否则会被转义成 \uXXXX

读写 JSON 文件

# 写入
with open('config.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

# 读取
with open('config.json', 'r', encoding='utf-8') as f:
    config = json.load(f)

indent=2 让输出带缩进,方便人类阅读。

JSON 不支持的数据类型

JSON 的类型系统比 Python 严格。以下类型不能直接序列化:

  • datetime → 手动转成字符串
  • set → 先转成 list
  • 自定义类的实例 → 需要自定义编码器
from datetime import datetime
import json

class User:
    def __init__(self, name, created_at):
        self.name = name
        self.created_at = created_at

u = User('Bob', datetime.now())

# 自定义编码函数
def encode_user(obj):
    if isinstance(obj, User):
        return {
            '__type__': 'User',
            'name': obj.name,
            'created_at': obj.created_at.isoformat()
        }
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"无法序列化 {type(obj)}")

json_str = json.dumps(u, default=encode_user, ensure_ascii=False)
print(json_str)

default 参数接收一个函数,遇到无法序列化的对象时调用。反序列化时,配合 object_hook 恢复成原始对象。

Note

如果项目里频繁遇到「自定义类与 JSON 互转」,考虑用 dataclasses 配合第三方库 dataclasses-json,能省很多手写转换代码。

csv:表格数据的轻量格式

CSV(Comma-Separated Values)是纯文本表格格式,Excel 和数据库都能直接读写。

写入 CSV

import csv

rows = [
    ['name', 'age', 'city'],
    ['Alice', '25', 'Beijing'],
    ['Bob', '30', 'Shanghai'],
]

with open('data.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerows(rows)
Warning

写 CSV 时必须加 newline=''。否则 Windows 下会在每行末尾多出一个空行。这是 csv 模块文档里的明确要求。

读取 CSV

import csv

with open('data.csv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

每行是一个列表,元素都是字符串。如果需要自动转数字,自己手动 int() / float()

用字典读写

如果表头固定,用 DictReaderDictWriter 更直观:

import csv

with open('data.csv', 'r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(f"{row['name']} 住在 {row['city']}")

with open('output.csv', 'w', newline='', encoding='utf-8') as f:
    fieldnames = ['name', 'age', 'city']
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({'name': 'Carol', 'age': '28', 'city': 'Shenzhen'})

字典方式代码可读性更好,而且不依赖列的顺序。

三种格式怎么选

格式优点缺点适用场景
pickle支持任意 Python 对象只限 Python,有安全风险临时缓存、内部数据传递
JSON跨语言、人类可读、安全类型支持有限API 接口、配置文件、数据交换
CSV简单、Excel 兼容不支持嵌套结构表格数据导出、简单数据集
Tip

如果要序列化复杂的嵌套数据结构,且需要跨语言,picklecsv 都不合适。JSON 是默认选择。如果 JSON 也不够(比如需要二进制数据),考虑 MessagePack、Protobuf 等更高效的格式。

小结

  • pickle 功能最强,但只限 Python 且不安全,别用来处理不可信数据。
  • json 是通用标准,适合 API 和配置文件,注意处理不支持的数据类型。
  • csv 适合简单表格,用 DictReader/DictWriter 代码更优雅。
  • 持久化前想清楚:数据是给谁用的?要不要跨语言?要不要人类可读?

序列化是连接「程序内存」和「外部世界」的桥梁。选对格式,数据就能顺畅地在文件、网络、数据库之间流动。


来源:参考了 runoob「Python Pickle 模块」和「Python JSON」、liaoxuefeng「序列化」、pythondoc「读写结构化数据」等,改写后所得。