'b'
模式,以二进制数据的形式读写,不进行任何转换,例如将换行符转换为/从特定于平台的值或使用字符编码解码/编码文本。
csv
模块是特殊的。csv 数据是文本数据,因此应该使用文本模式,但是 csv
模块默认使用 '\r\n'
在所有平台上终止行,并且 它总是将 '\r'
和 '\n'
都识别为换行符。如果您在文本模式下打开相应的文件(使用 通用换行符),则在 Windows 上会得到 '\r\r\n'
(破损的换行符)(os.linesep == '\r\n'
)。这就是 Python 2 文档中说必须使用二进制模式的原因。在 Python 3 中,使用文本模式,但应传递 newline=''
来禁用 通用换行符 模式。
如果要保留字段中嵌入的可能的换行符(如 '\r'
),还应禁用通用换行符。
notepad.exe
)来理解本地文件)。csv
是一个特例,在文本数据中使用二进制模式。 - jfst
时,\r\n
序列在输入时转换为\n
(输出时相反)。b
(二进制模式)不执行此类转换。CSV库可能通过忽略回车符号(每当遇到回车符号时)来处理它们。
编辑:刚注意到问题有所更改。
由于CSV文件并不是为人类读者而设计的,因此该库可以仅使用\n
(换行符LF)分隔符输出它们。唯一的真正缺点是MSWindows用户使用记事本打开文件时会显示不佳。CSV库还可以输出带有\r\n
(CR LF)的文件,因为大多数程序都防御MSDOS文本文件约定。
无论哪种方式,该库都可以通过b
(二进制)模式良好地进行写入。如果以t
(文本)模式打开,则行分隔符可能会出现像\r\n\n
这样稍微奇怪的东西。可能大多数CSV文件解析器会忽略CR,并认为LF LF表示结束一行,并跟随一个空(空白)行,它也将忽略它。
+
在man page中有解释:
w+ 可读可写模式。 如果文件不存在,则创建该文件,否则将截断该文件。 流定位在文件开头。
与w
不同之处在于,w+
允许读取和写入。
\n
)来解决...不过这是一个好答案。 - Joran Beasley'\r\n'
都取决于平台(os.linesep
)。在 Windows 上是这样的,在 OS X 上则不是。您不需要显式使用 't'
模式(它会在 Python 2 的 stdio 函数中传递,因此可能会启用平台相关的行为,例如将 Ctrl+Z 识别为输入的 EOF 字符)。csv
模块始终在输入时识别 '\r' 和 '\n' - jfs我从未得到过为什么不应该以二进制模式打开 ASCII 文件的好解释。
我从未见过以二进制模式打开文件会破坏数据。
我曾经见过在 ASCII 模式下打开文件修改或损坏检索到的数据,因此我以及我认为大多数经验丰富的 Python 程序员通常会以二进制模式打开文件,除非我们有某种保证文件中没有并且永远不会有二进制字符。
open('binary.txt', 'wb').write(b"1\n2\n3\n")
和 open('text.txt', 'w').write("1\n2\n3\n")
并尝试在 notepad.exe
中打开这两个文件。 - jfs在文本模式下打开文件会根据操作系统的不同处理换行符,因此CVS例程的作者必须确定他们想要更多的控制权 - 他们更愿意自己处理换行符。这可能使他们能够解决在一个操作系统下处理在另一个操作系统上创建的文件时遇到的不一致性问题 -- 在某些独特情况下,“文本读取”会导致问题。也可能没有发现错误,但他们想要避免未来的可能性。或者,由于他们必须处理换行符考虑,绕过文本处理可能会更快。
从逻辑上讲,由于无法控制正在读取的文件的操作系统源,因此使用二进制可能是一般情况下更好的选择。然而,写入文本文件时,最好使用文本模式,让核心例程处理当前操作系统的换行符。
“+”在Confused by python file mode "w+"中有所讨论。
+
表示您既想从文件中写入又想读取。 - jfs