Python 2的CSV写入器在Windows上产生错误的行终止符

45
根据其文档,csv.writer默认使用'\r\n'作为行终止符号。
import csv

with open("test.csv", "w") as f:
    writer = csv.writer(f)

    rows = [(0,1,2,3,4),
           (-0,-1,-2,-3,-4),
           ("a","b","c","d","e"),
           ("A","B","C","D","E")]           

    print writer.dialect.lineterminator.replace("\r", "\\r").replace("\n", "\\n")
    writer.writerows(rows)
    print writer.dialect.lineterminator.replace("\r", "\\r").replace("\n", "\\n")

这将打印

\r\n
\r\n

正如预期的那样。但是,创建的csv文件使用行终止符“\r\r\n”

0,1,2,3,4

0,-1,-2,-3,-4

a,b,c,d,e

A,B,C,D,E

这是一个 Bug 还是我在使用 csv.writer 方面有问题?

Python 版本:

ActivePython 2.6.2.2(ActiveState Software Inc.)基于 Python 2.6.2 (r262:71600,2009 年 4 月 21 日,15:05:37) [MSC v.1500 32 位(Intel)] 在 win32 上运行

在 Windows Vista 上。


2
@wierob:去掉.replace(...).replace(...),使用内置的repr()函数。 - John Machin
3个回答

71
在Python 2.x中,始终以二进制模式打开文件,如文档所述。 csv将\r\n写入您的文件,但是然后基础Windows文本文件机制会介入并将该\n更改为\r\n...总效果:\r\r\ncsv.writer文档中可以看到:
如果csvfile是文件对象,则应在差异性很大的平台上使用'b'标志打开它。
似乎有些人不愿意提及主要罪魁祸首的名称 :-)
编辑:如@jebob在对此答案的评论中提到的,并基于@Dave Burton的答案,为了在Python 2和3中处理这种情况,您应该执行以下操作:
if sys.version_info >= (3,0,0):
    f = open(filename, 'w', newline='')
else:
    f = open(filename, 'wb')

6
一个好的“特性”是,即使在不需要二进制模式的平台(例如Linux)上仍然可以以二进制模式打开,因此请始终使用二进制模式。 - Arafangion
4
从3.6版本开始,文档现在说:“如果csvfile是文件对象,则应该使用newline=''打开”。 - jebob
1
@jebob问题开始,标签,我的回答开始:都说Python 2.x。 - John Machin
我正在使用 f = sys.stdout,即使在Linux上使用Python 2.7,它仍然会产生这些回车符。有解决方法吗? - user5359531
在Linux上,即使在Python 2.7下,这仍然会在我的脚本中产生回车符。 - user5359531

26

很不幸,Python 3的csv模块与此略有不同,但是这段代码可以适用于Python 2和Python 3:

if sys.version_info >= (3,0,0):
    f = open(filename, 'w', newline='')
else:
    f = open(filename, 'wb')

这在我使用的Python 2或3上都无法工作,在Linux/Mac上仍然输出Windows风格的换行符。 - user5359531
1
这就是它应该做的事情,user5359531。.csv文件格式应该由以Windows风格的换行符"\r\n"结尾的行(记录)组成。如果省略了\r,那将是一个错误。 - Dave Burton

23
要在Python 2.7 csv写入器中更改行终止符,请使用以下代码: writer = csv.writer(f, delimiter = '|', lineterminator='\n') 这是一种更简单的方法,可以将默认分隔符从\r\n更改为其他字符。请注意保留原有的HTML标签。

2
虽然这适用于Windows上的Python 2和3,但它会在Linux机器上创建非标准文件:根据规范,CSV文件应该以\r\n结尾,而不是\n,无论平台如何。 - MestreLion
1
好观点,但有时为了完成特定任务,违反标准是必要的。 - Jason Callahan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接