Python csv模块默认quoting=csv.QUOTE_MINIMAL,仅对含分隔符的字段加引号,若含换行符的字段未被引号包裹,则被误判为记录分隔符导致解析失败;合规做法是读写均启用csv.QUOTE_ALL确保所有字段被引号包裹。

Python csv 模块本身不自动处理含特殊字符(如换行符、引号、逗号嵌套在字段内)的 CSV,必须显式配置 quoting 和 escapechar 才能正确解析——否则会报 csv.Error: newline inside string 或字段错位。
为什么默认 csv.reader 会读崩含换行符的字段
CSV 标准允许字段用双引号包裹,且引号内可含换行符;但 Python 默认使用 quoting=csv.QUOTE_MINIMAL,它只对含分隔符的字段加引号,不强制包裹所有字段。若原始数据里有未被引号包裹的换行符(比如导出时 bug 或手动编辑过),csv.reader 就会把它当成记录分隔符,直接截断。
- 确认是否启用了引号包裹:检查文件头几行,看字段是否统一用
"包裹 - 若字段含换行符但没被引号包围,这不是合规 CSV,
csv模块无法修复,得先清洗或换工具(如pandas.read_csv配lineterminator) - 合规做法是确保生成时用
quoting=csv.QUOTE_ALL,读取时对应设quoting=csv.QUOTE_ALL或csv.QUOTE_MINIMAL
quoting 参数怎么选:从 QUOTE_MINIMAL 到 QUOTE_ALL
不同 quoting 值决定哪些字段被引号包裹,直接影响能否安全容纳特殊字符:
-
csv.QUOTE_MINIMAL(默认):仅当字段含分隔符(如逗号)、引号或换行符时才加引号 → 安全,但要求输入严格合规 -
csv.QUOTE_ALL:所有字段都加引号 → 最稳妥,能兜住字段内含逗号/换行/引号的情况,但文件体积略大 -
csv.QUOTE_NONNUMERIC:非数字字段加引号,且自动转为 float → 少用,容易误转 ID 类字符串 -
csv.QUOTE_NONE:完全不加引号 → 必须配escapechar,且字段内不能出现分隔符,基本不用
实操建议:读取未知来源 CSV 时,优先试 quoting=csv.QUOTE_ALL;写入时明确用 quoting=csv.QUOTE_ALL 避免下游解析问题。
立即学习“Python免费学习笔记(深入)”;
字段含双引号时,doublequote 和 escapechar 怎么配合
CSV 中双引号本身需转义:标准做法是连续两个 "" 表示一个字面量 "(即 doublequote=True)。若原始数据用反斜杠转义(如 "),就得关掉 doublequote 并指定 escapechar='\'。
- 默认
doublequote=True:字段内""被解析为单个",无需额外设置 - 若遇到
csv.Error: quote character not allowed,可能是字段里混用了单引号和双引号,或quotechar没对齐(比如文件用'包裹,但代码仍用默认quotechar='"') - 改
quotechar很简单:csv.reader(f, quotechar="'"),但务必和文件实际一致
示例:含双引号的字段写入
import csv
with open('out.csv', 'w', newline='') as f:
writer = csv.writer(f, quoting=csv.QUOTE_ALL, doublequote=True)
writer.writerow(['He said "Hello"', '2024-04-01'])
→ 生成 "He said ""Hello""","2024-04-01"
编码错误和 BOM 头导致乱码怎么办
Windows 记事本保存的 CSV 常带 UTF-8 BOM(ufeff),直接用 open(..., encoding='utf-8') 会把 BOM 当成第一列内容,导致列名错位。
- 读取时用
encoding='utf-8-sig':自动剥离 BOM,兼容无 BOM 文件 - 避免用
encoding='gbk'猜编码——先用chardet检测:chardet.detect(open('file.csv', 'rb').read(10000)) - 写入时若需兼容 Excel,用
utf-8-sig;若明确要 GBK(如对接老系统),写入时指定encoding='gbk',但读取也得同步
关键点:BOM 不是字符编码问题,是文件头部标记;utf-8-sig 是解法,不是妥协。


















