8.2 数据持久化

在程序运行期间,数据都是存储在内存中,程序运行结束,数据就会消失。如果想要持久保存数据,就需要将其保存到磁盘中,称之为数据持久化。

8.2.1 pickle模块

在 Python 中,pickle 模块用于实现对象的序列化(serialization)和反序列化(deserialization),即将 Python 对象转换为字节流以便存储或传输,以及将字节流恢复为原始对象。这一过程也被称为 “封存”(pickling)和 “解封”(unpickling)。

核心函数:

  • pickle.dump(obj, file):将对象序列化后写入文件
  • pickle.load(file):从文件中读取字节流并反序列化为对象
  • pickle.dumps(obj):将对象序列化为字节流并返回
  • pickle.loads(bytes):将字节流反序列化为对象

举例:

import pickle

data = {
    'a': [1, 2.0],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
    }

with open('data.pickle', 'wb') as f:
    pickle.dump(data, f)


with open('data.pickle', 'rb') as f:
    data1 = pickle.load(f)

print(data1)

结果为:

{'a': [1, 2.0], 'b': ('character string', b'byte string'), 'c': {None, True, False}}

大多数 Python 内置类型(如列表、字典、类实例等)都可被序列化。需要注意的是使用 pickle 操作文件时,必须以二进制模式(wb、rb 等)打开。

8.2.2 json模块

JSON(JavaScript Object Notation)

JSON是一种轻量级的数据交换格式,可以在不同系统、不同编程语言之间传递数据,也可以作为配置文件或者简单数据库存储结构化数据。JSON独立于编程语言,几乎所有主流语言都支持JSON的解析和生成。

JSON 数据由两种基本结构组成:

  • 键值对集合(类似字典):
    • 用{ }包裹,格式:{"键1": 值1, "键2": 值2}
    • 键必须是字符串(用双引号包裹),值可以是多种类型。
  • 有序值列表(类似数组):
    • 用[ ]包裹,格式:[值1, 值2, 值3]

支持的值类型:

  • 字符串("hello")
  • 数字(整数123、浮点数3.14)
  • 布尔值(true、false)
  • 空值(null)
  • 嵌套的 JSON 对象或数组

示例:

{
    "name": "张三",
    "age": 20,
    "is_student": true,
    "courses": ["数学", "英语"],
    "address": {
        "city": "北京",
        "street": null
    }
}

json模块

Python 的 json 模块是处理 JSON 数据的核心工具,主要用于实现 Python 数据结构与 JSON 格式之间的相互转换。

核心功能:

  • 直接与文件交互:读写 JSON 文件:json.dump() 和 json.load()
  • 序列化:将 Python 对象转换为 JSON 字符串:json.dumps()
  • 反序列化:将 JSON 字符串转换为 Python 对象:json.loads()

Python 与 JSON 数据类型对应关系:

Python 类型 JSON 类型
dict object
list, tuple array
str string
int, float number
True true
False false
None null

举例:

import json

# 1. Python数据结构转JSON字符串(序列化)
python_data = {
    "name": "张三",
    "age": 20,
    "is_student": True,
    "courses": ["数学", "英语"],
    "scores": {"数学": 90, "英语": 85},
    "address": None
}

# 将Python对象转为JSON字符串
json_str = json.dumps(python_data, ensure_ascii=False, indent=2)
print("JSON字符串:")
print(json_str)

# 2. JSON字符串转Python数据结构(反序列化)
parsed_data = json.loads(json_str)
print("\n解析后的Python数据:")
print(f"姓名: {parsed_data['name']}")
print(f"课程: {parsed_data['courses']}")

# 3. 直接操作JSON文件
# 写入JSON文件
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(python_data, f, ensure_ascii=False, indent=2)
print("\n数据已写入data.json文件")

# 读取JSON文件
with open("data.json", "r", encoding="utf-8") as f:
    file_data = json.load(f)
print("\n从文件读取的JSON数据:")
print(f"年龄: {file_data['age']}")
print(f"成绩: {file_data['scores']}")

输出为:

JSON字符串:
{
  "name": "张三",
  "age": 20,
  "is_student": true,
  "courses": [
    "数学",
    "英语"
  ],
  "scores": {
    "数学": 90,
    "英语": 85
  },
  "address": null
}

解析后的Python数据:
姓名: 张三
课程: ['数学', '英语']

数据已写入data.json文件

从文件读取的JSON数据:
年龄: 20
成绩: {'数学': 90, '英语': 85}

常用参数说明:

  • ensure_ascii=False:保留非 ASCII 字符(如中文),不进行转义
  • indent=2:格式化输出 JSON 字符串,增加可读性
  • sort_keys=True:按键名对字典进行排序