Python 序列化 JSON/CSV/Pickle

1 min入门

Python 序列化 JSON/CSV/Pickle 的完整教学讲解。

json 序列化

基本写法:对象转 JSON 字符串 json.dumps(<对象>)

# 将 Python 对象转为 JSON 字符串
import json
data = {"name": "Tom", "age": 18}
s = json.dumps(data)  # '{"name": "Tom", "age": 18}'

基本写法:格式化输出 json.dumps(<对象>, indent=<缩进>, ensure_ascii=<布尔>)

# 缩进美化并保留中文字符
print(json.dumps(data, indent=2, ensure_ascii=False))

基本写法:JSON 字符串转对象 json.loads(<字符串>)

# 将 JSON 字符串解析为 Python 对象
obj = json.loads('{"name": "Tom"}')
print(obj["name"])  # Tom

基本写法:写入文件 json.dump(<对象>, <文件对象>)

# 将对象序列化写入文件
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

基本写法:从文件读取 json.load(<文件对象>)

# 从文件读取并解析 JSON
with open("data.json", encoding="utf-8") as f:
    obj = json.load(f)

基本写法:排序键输出 json.dumps(<对象>, sort_keys=True)

# 按键名排序输出
print(json.dumps({"b": 1, "a": 2}, sort_keys=True))

基本写法:自定义序列化 json.dumps(<对象>, default=<函数>)

# 自定义非内置类型的序列化逻辑
from datetime import datetime
def default(o):
    if isinstance(o, datetime):
        return o.isoformat()
    raise TypeError

print(json.dumps({"t": datetime.now()}, default=default))

基本写法:自定义反序列化 json.loads(<字符串>, object_hook=<函数>)

# 解析时转换字典结构
def as_date(d):
    if "date" in d:
        return d["date"]
    return d

obj = json.loads('{"date": "2024-01-01"}', object_hook=as_date)

基本写法:JSONEncoder 子类 class <类>(json.JSONEncoder):

# 通过子类化编码器统一处理类型
class MyEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, set):
            return list(o)
        return super().default(o)

print(json.dumps({1, 2}, cls=MyEncoder))

csv 读写

基本写法:写入 CSV csv.writer(<文件对象>)

# 写入 CSV 文件
import csv
with open("data.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.writer(f)
    w.writerow(["name", "age"])
    w.writerow(["Tom", 18])

基本写法:读取 CSV csv.reader(<文件对象>)

# 读取 CSV 文件内容
with open("data.csv", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)  # ['name', 'age']

基本写法:字典方式写入 csv.DictWriter(<文件对象>, fieldnames=<字段列表>)

# 按字典结构写入
fields = ["name", "age"]
with open("data.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.DictWriter(f, fieldnames=fields)
    w.writeheader()
    w.writerow({"name": "Tom", "age": 18})

基本写法:字典方式读取 csv.DictReader(<文件对象>)

# 按字典结构读取
with open("data.csv", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["name"])  # Tom

基本写法:指定分隔符与引号 csv.writer(<文件>, delimiter=<分隔符>, quotechar=<引号字符>)

# 自定义分隔符(如 TSV 制表符分隔)
with open("data.tsv", "w", newline="") as f:
    w = csv.writer(f, delimiter="\t")
    w.writerow(["a", "b"])

基本写法:处理空值与方言 csv.register_dialect(<名称>, **<参数>)

# 注册自定义方言复用配置
csv.register_dialect("pipes", delimiter="|")
with open("data.txt", "w", newline="") as f:
    w = csv.writer(f, dialect="pipes")
    w.writerow(["a", "b"])

pickle 序列化

基本写法:对象转字节串 pickle.dumps(<对象>)

# 将任意 Python 对象序列化为字节
import pickle
data = {"name": "Tom", "list": [1, 2, 3]}
b = pickle.dumps(data)

基本写法:字节串转对象 pickle.loads(<字节串>)

# 从字节反序列化为 Python 对象
obj = pickle.loads(b)
print(obj["name"])  # Tom

基本写法:写入文件 pickle.dump(<对象>, <文件对象>)

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

基本写法:从文件读取 pickle.load(<文件对象>)

# 从文件反序列化对象
with open("data.pkl", "rb") as f:
    obj = pickle.load(f)

基本写法:指定协议版本 pickle.dump(<对象>, <文件>, protocol=<版本>)

# 使用高版本协议提升效率
with open("data.pkl", "wb") as f:
    pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)

基本写法:批量序列化 pickle.dump + 循环

# 多次调用 dump 可写入多个对象
with open("data.pkl", "wb") as f:
    for item in [obj1, obj2, obj3]:
        pickle.dump(item, f)

# 读取时循环 load 直到 EOFError
with open("data.pkl", "rb") as f:
    while True:
        try:
            print(pickle.load(f))
        except EOFError:
            break

shelve 持久化字典

基本写法:打开 shelve 数据库 shelve.open(<文件名>)

# 像字典一样持久化存储对象
import shelve
db = shelve.open("mydb")
db["user"] = {"name": "Tom", "age": 18}
print(db["user"]["name"])  # Tom
db.close()

基本写法:上下文管理 with shelve.open(<文件名>) as <变量>:

# 使用 with 自动关闭
with shelve.open("mydb") as db:
    db["key"] = "value"
    for k in db:
        print(k, db[k])

基本写法:写回模式 shelve.open(<文件名>, writeback=True)

# 启用写回,修改可变值时自动同步
with shelve.open("mydb", writeback=True) as db:
    db["list"].append("new")  # 直接修改生效

msgpack 与 orjson(高性能扩展)

基本写法:orjson 高速序列化 orjson.dumps(<对象>)

# orjson 性能远高于标准 json(返回字节)
import orjson
b = orjson.dumps(data, option=orjson.OPT_INDENT_2)
obj = orjson.loads(b)

基本写法:orjson 保留中文 orjson.dumps(<对象>, option=orjson.OPT_NON_STR_KEYS)

# orjson 默认即返回 UTF-8 字节,无需 ensure_ascii
import orjson
print(orjson.dumps({"名": "Tom"}))  # b'{"name":"Tom"}'