Skip to content

文件、路径与序列化 ​

学习目标 ​

  • 用 pathlib.Path 跨平台处理路径。
  • 正确打开、读取、写入文本与二进制文件。
  • 掌握 JSON、CSV 和 pickle 的适用边界。

核心知识点 ​

路径是资源位置,文件对象负责读写。Path 会按当前平台拼接路径;文本读写要指定编码。序列化把内存对象转换为可保存格式,JSON 适合跨语言数据,pickle 只适合可信来源的 Python 数据。

常用用法 ​

pathlib.Path 拼接路径 ​

python
from pathlib import Path

root = Path("data")
file_path = root / "reports" / "summary.txt"
print(file_path.as_posix())
# 输出:data/reports/summary.txt

使用 / 拼接而不是手写 "/" 或 "\\",代码能适配 Windows 和 Unix。

Path.exists()、is_file() 与 is_dir() ​

python
from pathlib import Path

path = Path(".")
print(path.exists(), path.is_dir(), path.is_file())
# 输出:True True False

检查结果可能随运行目录变化;不要把当前工作目录误认为脚本所在目录。

Path.mkdir() ​

python
from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as name:
    folder = Path(name) / "reports" / "2026"
    folder.mkdir(parents=True, exist_ok=True)
    print(folder.is_dir())
    # 输出:True

parents=True 创建缺失的父目录,exist_ok=True 允许目录已存在。

open() 与上下文管理 ​

python
from tempfile import TemporaryDirectory
from pathlib import Path

with TemporaryDirectory() as name:
    path = Path(name) / "note.txt"
    with path.open("w", encoding="utf-8") as file:
        file.write("hello\n")
    print(path.read_text(encoding="utf-8").strip())
    # 输出:hello

with 会在离开代码块时关闭文件,即使中途抛出异常。

Path.read_text() 与 write_text() ​

python
from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as name:
    path = Path(name) / "message.txt"
    path.write_text("你好", encoding="utf-8")
    content = path.read_text(encoding="utf-8")
    print(content)
    # 输出:你好

小文件可用这两个便捷方法;大文件或流式处理使用 open 逐行读取。

JSON 序列化 ​

python
import json

payload = {"name": "Ada", "scores": [98, 100]}
text = json.dumps(payload, ensure_ascii=False, sort_keys=True)
restored = json.loads(text)
print(text, restored["scores"][0])
# 输出:{"name": "Ada", "scores": [98, 100]} 98

JSON 只支持有限的值类型;日期、Decimal 等对象要先转换成约定的字符串或数字。

CSV 读写 ​

python
import csv
import io

buffer = io.StringIO()
writer = csv.DictWriter(buffer, fieldnames=["name", "score"])
writer.writeheader()
writer.writerow({"name": "Ada", "score": 98})
print(buffer.getvalue().strip())
# 输出:name,score\nAda,98

使用 csv 模块而不是手写逗号拼接,能处理引号、逗号和换行。

不常用但需要知道 ​

Path.glob() ​

python
from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as name:
    root = Path(name)
    (root / "a.txt").write_text("a", encoding="utf-8")
    (root / "b.md").write_text("b", encoding="utf-8")
    print(sorted(path.name for path in root.glob("*.txt")))
    # 输出:['a.txt']

glob 查找当前层,rglob 可递归;注意返回结果顺序不应默认稳定,展示时自行排序。

Path.resolve() ​

python
from pathlib import Path

resolved = Path(".").resolve()
print(resolved.is_absolute())
# 输出:True

解析真实路径可能访问文件系统并处理符号链接,安全校验时要结合允许的根目录。

pickle.dumps() ​

python
import pickle

data = pickle.dumps({"value": 3})
restored = pickle.loads(data)
print(restored)
# 输出:{'value': 3}

绝不从不可信来源 loads pickle;它可以执行任意代码。跨语言或外部交换优先 JSON。

易混点 ​

  • Path 对象与字符串可用 str(path) 转换,传给大多数现代 API 时不必手动拼接。
  • read_text() 一次性读入内存,大文件应逐行处理。
  • 文本模式需要 encoding;二进制模式用 rb/wb 并读写 bytes。
  • json.dumps 返回字符串,json.dump 写入文件对象;loads/load 同理。
  • pickle 不是安全的数据交换格式。

课后小问 ​

  1. 为什么文件读写推荐 with path.open(...)? 答案:上下文管理器会保证文件及时关闭。 解析:即使写入过程抛异常,也会执行清理,避免文件句柄泄漏和缓冲区未刷新。

  2. JSON 和 pickle 该怎样选择? 答案:跨语言或不可信边界用 JSON;仅在可信 Python 内部保存复杂对象时才考虑 pickle。 解析:pickle 能表达更多 Python 对象,但加载不可信数据存在代码执行风险。

本节小结 ​

以 Path 处理路径,以 with 管理文件生命周期,以 JSON/CSV 交换普通数据;pickle 只在明确可信的内部场景使用。

快速回顾 ​

  • 路径:Path、/、exists、glob
  • 文件:open、read_text、write_text
  • 文本编码:显式 encoding="utf-8"
  • 序列化:json.dumps/loads、csv
  • 安全边界:不要加载不可信 pickle