文件、路径与序列化
学习目标
- 用
pathlib.Path跨平台处理路径。 - 正确打开、读取、写入文本与二进制文件。
- 掌握 JSON、CSV 和 pickle 的适用边界。
核心知识点
路径是资源位置,文件对象负责读写。Path 会按当前平台拼接路径;文本读写要指定编码。序列化把内存对象转换为可保存格式,JSON 适合跨语言数据,pickle 只适合可信来源的 Python 数据。
常用用法
pathlib.Path 拼接路径
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()
from pathlib import Path
path = Path(".")
print(path.exists(), path.is_dir(), path.is_file())
# 输出:True True False检查结果可能随运行目录变化;不要把当前工作目录误认为脚本所在目录。
Path.mkdir()
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())
# 输出:Trueparents=True 创建缺失的父目录,exist_ok=True 允许目录已存在。
open() 与上下文管理
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())
# 输出:hellowith 会在离开代码块时关闭文件,即使中途抛出异常。
Path.read_text() 与 write_text()
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 序列化
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]} 98JSON 只支持有限的值类型;日期、Decimal 等对象要先转换成约定的字符串或数字。
CSV 读写
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()
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()
from pathlib import Path
resolved = Path(".").resolve()
print(resolved.is_absolute())
# 输出:True解析真实路径可能访问文件系统并处理符号链接,安全校验时要结合允许的根目录。
pickle.dumps()
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不是安全的数据交换格式。
课后小问
为什么文件读写推荐
with path.open(...)? 答案:上下文管理器会保证文件及时关闭。 解析:即使写入过程抛异常,也会执行清理,避免文件句柄泄漏和缓冲区未刷新。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
阿源的知识库