Python 读取 CSV:正确处理逗号、换行与 UTF-8 BOM

举报
魔幻精灵 发表于 2026/10/26 11:24:27 2026/10/26
【摘要】 用 Python 标准库读取包含逗号和换行的 CSV,说明 newline、UTF-8 BOM 与列数校验,并提供可运行的虚拟数据示例。

处理导出的数据表时,最容易写出的代码是逐行读取,再用 split(‘,’) 切分字段。它对简单样例有效,但备注里一旦出现逗号,列就会错位。本文用一个小例子说明如何用 Python 标准库读取 CSV,并在读取入口检查数据结构。示例是教学用虚拟数据,不涉及真实业务记录。

1. 先看一条容易误读的数据

下面的 CSV 有三列,第二条记录的备注包含逗号,第三条记录的备注包含换行。双引号包住的内容仍然属于一个字段:

name,quantity,note
apple,2,"fresh, red"
pear,3,"line one
line two"

对第二条记录直接 split(‘,’) 会得到四段;按物理行分别处理第三条记录,又会把同一条数据拆开。CSV 的记录边界与文本换行并不总是一回事,因此应让解析器处理引号和分隔符。

2. 用 DictReader 按列名读取

将上面的数据保存为 data.csv,再运行以下脚本:

import csv
with open('data.csv', encoding='utf-8-sig', newline='') as f:
    reader = csv.DictReader(f)
    expected = ['name', 'quantity', 'note']
    if reader.fieldnames != expected:
        raise ValueError(f'表头不符合预期: {reader.fieldnames!r}')
    total = 0
    for record_no, row in enumerate(reader, start=1):
        if None in row or any(v is None for v in row.values()):
            raise ValueError(f'第 {record_no} 条记录列数不匹配')
        try:
            quantity = int(row['quantity'])
        except ValueError as exc:
            raise ValueError(f'第 {record_no} 条记录数量不是整数') from exc
        if quantity < 0:
            raise ValueError(f'第 {record_no} 条记录数量不能为负数')
        total += quantity
        print(row['name'], quantity, repr(row['note']))
    print('合计:', total)

这份示例的数量合计应为 5。repr() 会把备注中的换行显示为转义形式,方便观察字段是否完整。这里的 record_no 是数据记录序号,并非文件物理行号。

3. 两个参数各管一件事

newline=‘’ 让 csv 模块自行处理换行,尤其是带引号字段内的换行。encoding=‘utf-8-sig’ 在读取时可去除文件开头的 UTF-8 BOM,也能读取不带 BOM 的 UTF-8 文件。它不是通用编码探测器;如果来源明确为 GBK,应使用对应编码,不能靠忽略解码错误来“修好”数据。

4. 在入口发现结构问题

DictReader 负责解析,不负责判断业务值是否合理。示例显式检查表头、字段数、整数格式与非负约束,是为了让错误尽早暴露。表头顺序检查是本例的数据约定;若业务允许列顺序变化,应改为核对列名集合,同时检查重复列名。空字符串也不等于缺列,需要按字段规则分别处理。
对于大文件,可以保持逐条处理,只累计必要结果,不必先把 reader 转成列表。小脚本一旦接入定时任务,更应让异常清楚说明问题位置,避免悄悄吞掉坏数据。
参考:

  • Python 官方文档:《csv — CSV File Reading and Writing》
  • Python 官方文档:《codecs — Codec Registry and Base Classes》
    本文由 AI 辅助编写,示例用于解释 CSV 解析与校验方法。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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