Python 读取 CSV:排查首列表头里的隐藏 BOM

举报
yd_239549656 发表于 2026/10/30 09:01:30 2026/10/30
【摘要】 用可复现样例说明 UTF-8 BOM 为什么会影响 DictReader 的首列字段名,并验证 utf-8-sig 与 newline='' 对中文、逗号及字段内换行的处理。

同一份 CSV,在表格软件里看得到 name 列,Python 却报 KeyError: ‘name’。这种情况可以先看字段名的真实表示,不必立刻修改数据。

1. 先看 repr,不凭肉眼判断

下面的样例会在临时目录中构造一份带 UTF-8 BOM 的 CSV,不读取或修改业务文件。

import csv
from pathlib import Path
from tempfile import TemporaryDirectory

text = 'name,note\r\n小明,"上海,浦东"\r\n小红,"第一行\r\n第二行"\r\n'

with TemporaryDirectory() as folder:
    path = Path(folder) / "sample.csv"
    path.write_bytes(text.encode("utf-8-sig"))

    with path.open(encoding="utf-8", newline="") as f:
        reader = csv.DictReader(f)
        print(repr(reader.fieldnames[0]))
        row = next(reader)
        print("name" in row)

本次自检输出:

'\ufeffname'
False

字段名实际上是 \ufeffname,和 name 不相等。示例中的字符串以 UTF-8 BOM 开头;使用普通 utf-8 解码时,开头的标记会成为字符串里的字符。

2. 在解码入口处理 BOM

对已确认是 UTF-8、可能带 BOM 的输入,可以改用 utf-8-sig:

with path.open(encoding="utf-8-sig", newline="") as f:
    reader = csv.DictReader(f)
    print(reader.fieldnames)
    for row in reader:
        print(row["name"], repr(row["note"]))

这段代码放在上例 TemporaryDirectory 的 with 块内运行。结果为:

['name', 'note']
小明 '上海,浦东'
小红 '第一行\r\n第二行'

utf-8-sig 在读取时会处理文件开头的可选 BOM;同一份不带 BOM 的 UTF-8 样例也能正常读取。这里解决的是文件开头的标记,不是清洗所有字段中的不可见字符。官方说明见 Python codecs 文档的 encodings.utf_8_sig 小节。

3. 保留 CSV 对换行和引号的处理

样例故意包含两种内容:字段内的逗号,以及用引号包裹的跨行字段。不要用 split(“,”) 或把每个物理行直接当成一条记录。

Python csv 文档建议文件对象以 newline=“” 打开,让 csv 模块处理换行。上面的实验也验证了跨行字段中的 CRLF 被保留。数据有自己的分隔符或引号约定时,应明确配置 csv 的对应参数。

4. 这不是编码自动识别

utf-8-sig 不会把 GBK、UTF-16 等编码自动变成 UTF-8。示例使用严格解码;遇到无法解码的数据应核对来源编码,不能靠 errors=“ignore” 静默丢失字符。

示例只演示读取合法的两列表格,不替代导入时的列名、必填值、重复表头、字段数量和业务类型校验。本次在本机 Python 3.9.6 中检查了带 BOM、不带 BOM、字段内逗号、跨行字段、仅表头和非法字节的情况;没有宣称覆盖所有 CSV 方言或在 Windows 上实测。

官方参考资料:

  • Python csv:docs.python.org/3/library/csv.html
  • Python codecs / encodings.utf_8_sig:docs.python.org/3/library/codecs.html#encodings.utf_8_sig

本文由 AI 辅助整理,示例为本次独立构造并在本机执行的教学数据。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。