Python 中的 CSV 添加了一个额外的回车符,在 Windows 上

import csv


with open('test.csv', 'w') as outfile:
writer = csv.writer(outfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
writer.writerow(['hi', 'dude'])
writer.writerow(['hi2', 'dude2'])

上面的代码生成一个文件 test.csv,在每一行都有一个额外的 \r,如下所示:

hi,dude\r\r\nhi2,dude2\r\r\n

而不是预期的

hi,dude\r\nhi2,dude2\r\n

为什么会发生这种情况,或者这实际上是人们想要的行为?

274435 次浏览

Python 3:

官方的csv文档建议在所有平台上使用newline=''来__abc1文件到禁用通用换行转换:

with open('output.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
...

CSV编写器以lineterminator的方言结束每一行,对于所有平台上的默认excel方言,它是'\r\n',因为这是RFC 4180所推荐的。


Python 2:

在Windows上,在将文件传递给csv.readercsv.writer之前,始终以二进制模式("rb""wb")打开文件。

虽然文件是一个文本文件,CSV被相关的库视为二进制格式,用\r\n分隔记录。如果分隔符以文本模式编写,Python运行时将\n替换为\r\n,因此在文件中观察到\r\r\n

看到之前的答案

虽然@john-machin给出了一个很好的答案,但它并不总是最好的方法。例如,它不能在Python 3上工作,除非您将所有输入编码到CSV写入器。而且,如果脚本想使用sys. exe,它也不能解决这个问题。Stdout为流。

我建议在创建写入器时设置'lineterminator'属性:

import csv
import sys


doc = csv.writer(sys.stdout, lineterminator='\n')
doc.writerow('abc')
doc.writerow(range(3))

这个例子可以在python2和python3上运行,不会产生不必要的换行符。但是请注意,它可能会产生不需要的换行符(在Unix操作系统上省略LF字符)。

然而,在大多数情况下,我认为这种行为比将所有CSV都视为二进制格式更可取,也更自然。我提供这个答案作为您考虑的替代方案。

在Python 3中(我还没有在Python 2中尝试过),您也可以简单地这样做

with open('output.csv','w',newline='') as f:
writer=csv.writer(f)
writer.writerow(mystuff)
...

根据文档

在文档的脚注中有更多的说明:

如果没有指定newline= ",则在带引号的字段中嵌入换行符 不能正确解释,并且在使用\r\n linends写一个额外的\r将被添加。应该一直如此 指定newline= "是安全的,因为CSV模块自己执行

.(通用)换行处理

你必须添加属性newline="\n"来打开函数,就像这样:

with open('file.csv','w',newline="\n") as out:
csv_out = csv.writer(out, delimiter =';')

可以在csv writer命令中引入lineterminator = ' \ n '参数。

import csv
delimiter='\t'
with open('tmp.csv', '+w', encoding='utf-8') as stream:
writer = csv.writer(stream, delimiter=delimiter, quoting=csv.QUOTE_NONE, quotechar='',  lineterminator='\n')
writer.writerow(['A1' , 'B1', 'C1'])
writer.writerow(['A2' , 'B2', 'C2'])
writer.writerow(['A3' , 'B3', 'C3'])
注意,如果你使用DictWriter,你将从open函数和writerow函数中获得新行。 你可以在open函数中使用newline= "来删除多余的换行符