当前位置:首页 > 文章列表 > 文章 > python教程 > Python csv 文件为什么要用 newline 空字符串打开

Python csv 文件为什么要用 newline 空字符串打开

来源:17golang原创 2026-11-12 02:45:09 0浏览 收藏

Python 使用 csv 模块读写文本文件时,通常应给 open() 传入 newline=""。它让文本层保留换行字符,由 csv 模块处理记录边界与引号内换行,避免两层转换相互干扰。这个参数并不是“删除换行”,也不表示每条记录之间没有分隔。

我更愿意把它当作一个明确的职责约定:编码交给文本流,CSV 结构交给 reader 或 writer。这样讨论空行、多行备注和跨平台导出时,就不必把所有现象都归因于文件编码。

官方文档:https://docs.python.org/3/library/csv.html

先分清文本流与 CSV 的职责

文件中的字节、文本流返回的字符串、CSV 解析后的字段,是不同层面的对象。文本流既负责字符编解码,也可以转换换行;CSV 解析器则负责分隔符、引号和记录边界。多行字段允许一条逻辑记录占用多个物理行,因此不能把每个换行都理解成下一条记录。

设置位置控制的事情常见误解
open 的 encoding字节与字符的转换指定 UTF-8 就能解决所有空行
open 的 newline文本层如何识别或转换换行空字符串会把换行清除
writer 的 lineterminator写出记录的结束字符与 open 的 newline 完全相同
CSV 的引号规则区分字段内容和结构字符直接按行切分也能完整解析
文本换行设置与CSV解析职责的分组关系
结构说明图:文件字节与文本流属于输入边界,CSV 解析器与字段属于结构边界;连线表示职责关联,不是运行过程截图。

读取时保留字段里的原始换行

默认的 newline=None 会在读取时把 CR、LF、CRLF 行结束形式归一成 LF。指定空字符串仍支持通用换行识别,但向上层返回未转换的行结束字符。对 CSV 来说,这可以避免在 reader 识别字段之前,文本层就改变引号内原有的换行内容。

假设“备注”字段包含 CRLF,使用默认文本读取后,CSV 可能仍能解析成一条记录,但字段里的 CRLF 已变成 LF。因此,“没有报错”和“字段内容保真”是两个判断标准。我的选择是直接使用文档建议的空字符串设置,而不依赖数据刚好没有多行字段。

import csv

# 交给 csv.reader 解释引号中的换行;文本层不预先替换
with open("feedback.csv", "r", encoding="utf-8", newline="") as source:
    reader = csv.DictReader(source)
    for row in reader:
        note = row["备注"]
        # repr 让回车、换行可见,不靠屏幕换行判断字段内容
        print(row["编号"], repr(note))

这个例子约定输入有“编号”和“备注”表头,遇到缺列还需要应用自己的业务处理。这里用 repr 帮助读者观察控制字符;本文没有执行示例,也不声称展示了本地输出。若数据量很大,逐条处理 reader 返回的记录即可,不必为了读取 CSV 先把整个文件装进列表。

写入时避免换行被重复转换

csv 的默认 excel 方言通常用 CRLF 结束一条记录。若文本层又把其中的 LF 转成平台默认 CRLF,就可能形成 CRCRLF。某些读取程序把多出来的回车解释成额外行边界,表现为每条记录之间多空行;具体显示方式仍取决于读取工具。

import csv

records = [
    {"编号": "F-204", "备注": "需要复核\r\n已联系负责人"},
    {"编号": "F-205", "备注": "已确认"},
]

# 文本层不转换换行;writer 负责分隔、引号和记录结束符
with open("feedback.csv", "w", encoding="utf-8", newline="") as target:
    writer = csv.DictWriter(target, fieldnames=["编号", "备注"])
    writer.writeheader()
    writer.writerows(records)

示例中的多行备注属于一个字段,writer 负责按方言规则添加必要引号。newline="" 保证文本层不再次改写 writer 产生的换行。不要在 writerow 之后补写换行,也不要手动把每个字段拼接成逗号分隔字符串,否则含逗号、引号或换行的字段会增加转义错误。

CSV writer与文本层换行设置的静态关系
结构说明图:记录结束符受 writer 设置约束,文本层受 newline 设置约束,编码决定文件字节表达;这三个配置承担不同责任。

如果对接协议要求使用 LF,保留 open 的空字符串设置,并在 writer 上明确设置记录结束符:

import csv

# 对接方明确要求 LF 时,在 writer 上设置记录结束符
with open("export-lf.csv", "w", encoding="utf-8", newline="") as target:
    writer = csv.writer(target, lineterminator="\n")
    writer.writerow(["编号", "说明"])
    writer.writerow(["F-206", "一条记录"])

改变 lineterminator 影响写出的记录边界,不会自动统一字段本身包含的换行。如果业务还要求备注内容统一换行,应在业务字段处理层明确实施,而不是期待 CSV 写入参数顺便清洗内容。

跨平台使用与常见疑问

这个做法适用于 Python 3 标准库 csv 配合文本文件对象读写,也适用于 DictReader、DictWriter。不是只有 Windows 才值得设置:写出重复回车的现象在使用 CRLF 文本转换的平台上更突出,而读取时保留多行字段的原始换行同样有意义。

newline="" 与 newline="\n" 能互换吗?

写入时两者都不进行文本层换行转换,但读取行为不同:后者只按指定的 LF 识别行结束,不等于空字符串启用的通用换行识别。为了保持读写约定一致,我会优先采用 csv 文档推荐的空字符串形式。

已经有空白行,设置参数会自动修复吗?

不会。参数影响本次读写,不会修复已经写入的文件。如果业务要清理历史空记录,应先定义空记录的含义;包含换行的合法字段与真正的空记录不能一概删除。

二进制模式能绕开这个问题吗?

标准 csv.reader 接收字符串迭代,writer 写出文本,直接把 rb 或 wb 文件对象交给它们不符合这套接口。已有二进制流时可以通过 TextIOWrapper 建立文本层,并明确 encoding 与 newline;关闭包装流也会影响底层流的生命周期。

中文乱码或者表头出现 BOM 怎么处理?

这是编码约定的问题,不能靠 newline 修复。与数据来源约定编码;如果已知文件含 UTF-8 BOM,可按实际格式使用 utf-8-sig 读取。不要在不清楚来源时用忽略解码错误掩盖数据损坏。

选择参数时先确认两件事:是否由 csv 模块负责结构,以及对接方要求哪种记录结束符。前者决定文本层保留换行,后者决定 writer 的设置。文本流详细规则见 https://docs.python.org/3/library/io.html#io.TextIOWrapper,open 参数说明见 https://docs.python.org/3/library/functions.html#open。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Python Protocol 怎样表达结构化接口Python Protocol 怎样表达结构化接口
上一篇
Python Protocol 怎样表达结构化接口
Python nullcontext 怎样统一可选上下文管理
下一篇
Python nullcontext 怎样统一可选上下文管理
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    987次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    991次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1114次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1083次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    929次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码