(九)CSV 的字段、引号与类型恢复
1. 用读写器处理分隔符与换行
CSV 适合一行记录、若干列字段的表格。标题本身也可能有逗号、双引号或换行,不能直接对每行执行 split(","):
# newline="" 让 csv 模块处理行尾与带引号字段中的换行。
import csv
from pathlib import Path
path = Path("books.csv")
with path.open("w", encoding="utf-8", newline="") as stream:
writer = csv.writer(stream)
writer.writerow(["title", "finished"])
writer.writerow(["Python, 入门", "0"])
writer.writerow(['NumPy "实践"\n手册', "1"])
with path.open(encoding="utf-8", newline="") as stream:
reader = csv.DictReader(stream)
for row in reader:
print(row["title"].replace("\n", "/"), row["finished"] == "1")输出 Python, 入门 False 和 NumPy "实践"/手册 True。写入器为需要的字段加入引号,把内部双引号按 CSV 规则转义;读取器把跨物理行的带引号内容还原为同一个字段。
DictReader 默认用首条记录作为字段名,之后交回字典;DictWriter(stream, fieldnames=[...]) 按指定列顺序写字典,writeheader() 写表头。CSV 的记录数不一定等于文本物理行数,错误提示中的“第几条记录”与“第几行文本”要分清。CSV 读写
2. 文本列需要明确恢复类型
# StringIO 提供内存中的文本文件接口,便于观察 CSV 对值的处理。
import csv
from io import StringIO
stream = StringIO(newline="")
csv.writer(stream).writerow([None, "", 0])
stream.seek(0)
print(next(csv.reader(stream)))输出 ['', '', '0']。CSV 默认交回文本;这里 None 与空字符串都写成空字段,读回来后已无法从字段本身区分它们。列中要保留“未填写”的含义,就为该列约定标记或增加对应状态字段。
综合书目 CSV 固定使用 title,finished,tags 三列,完成状态写 0 或 1。标签列表在一个单元格中保存成 JSON 数组,因此标签本身的逗号与分隔符仍能完整恢复。它由 CSV 管理外层单元格,由 JSON 管理标签数组,两个解析步骤各处理自己的结构。