我注意到在文档中他们总是用'wb'打开一个CSV文件。 为什么'b'? 我知道b代表二进制模式,但是你什么时候使用二进制模式(我猜想CSV文件不是二进制模式)。 如果相关我是从arcpy.da.SearchCursor()查询的结果写入CSV
编辑:根据这个答案注意到wb+用于编写二进制文件。 什么包括+呢?
如果有任何非ascii字符你应该使用二进制模式...在二进制模式下打开将永远不会改变或损害你的数据afaik,但有时打开ascii模式将删除或更改字符...因此我总是打开 二进制模式(即使使用ascii数据)
@JoranBeasley:没有"ascii模式"这样的东西。 改为使用术语"文本模式"(文本文件的字符编码可以是任何东西)。
阅读您已链接的问题的答案 - +表示您希望同时写入和从文件中读取。
使用'b'模式,按原样读取/写入二进制数据,无需进行任何转换,例如将换行符转换为特定于平台的值或使用字符编码对文本进行解码/编码。
csv模块很特别。 csv数据是文本,因此可以预期文本模式,但csv模块默认使用'
'来终止所有平台上的行,并且它始终将'
'和'
'都识别为换行符。 如果您在文本模式下打开相应的文件(使用通用换行符),那么您将在Windows上获得'
'(损坏的换行符)(os.linesep == '
')。 这就是Python 2文档说你必须使用二进制模式的原因。 在Python 3中,使用了文本模式,但是您应该传递newline=''以禁用通用换行模式。
如果要保留字段中嵌入的可能换行符(例如'
'),您还需要禁用通用换行符。
要挑剔,传递newline=不会禁用通用换行模式。从文档:"如果是,启用通用换行模式,但行结尾返回给调用者未翻译。"
文件打开默认是使用文本模式,它可以在写入时将" n"字符转换为特定于平台的表示,并在读取时返回。
在Windows中,这将修改从' n'到' r n'的换行符,这将在其他应用程序/平台中打开CSV文件时出现问题。
因此,在打开二进制文件时,您应该将'b'附加到模式值以在二进制模式下打开文件,这将提高可移植性。在没有这种区别的系统上,添加"b"无效。
注意:'w +'截断文件。
模式'r +','w +'和'a +'打开文件进行更新(读写)。
详情如下:https://docs.python.org/2/library/functions.html#open
什么是"截断"文件,是否意味着替换?
相反。文本模式提高了代码的可移植性(您可以读取在其他平台上编写的文本,本地编写的文件可以通过特定于平台的程序(如notepad.exe)来理解)。 csv是一种特殊情况,其中二进制模式用于文本数据
截断表示如果文件不存在则会创建该文件,如果文件存在则会被覆盖。所以是的,简单来说就意味着取代。
我同意,"文本模式增加了可移植性,而csv只是一种特殊情况,其中二进制模式用于文本数据"。
特别是对于Python csv模块,答案很简单:它是文档所要求的。
If csvfile is a file object, it must be opened with the ‘b’ flag on platforms where that makes a difference.
资料来源:https://docs.python.org/2.7/library/csv.html#csv.reader
由于在文本模式下打开文件会根据操作系统对核心代码的处理方式进行不同的处理,因此CVS例程作者必须确定他们需要更多控制 - 他们更愿意自己处理换行。这可能使他们能够解决在另一个操作系统上创建的一个操作系统下处理文件时遇到的不一致问题 - 在某些特殊情况下,"文本读取"会改变问题。它也可能没有发现错误,但他们希望避免未来的可能性。或者,也可能是因为他们不得不处理换行注意事项,绕过文本处理可能会更快。
从逻辑上讲,由于无法控制正在读取的文件的OS源,因此使用二进制文件可能是更好的方法。但是,编写一个文本文件可能会很好地将其留给核心例程来使用文本模式处理当前操作系统的换行符。
在python文件模式"w +"的困惑中讨论了"+"
我从来没有收到过关于为什么我不能在二进制模式下打开ascii文件的好解释。
我从未见过以二进制模式打开文件来破坏数据。
我已经看到以ascii模式打开文件,改变或损坏正在检索的数据,我和我认为大多数经验丰富的python程序员都会以二进制模式打开文件,除非我们有某种保证,没有,也永远不会文件中的二进制字符。
要理解原因,请写open(binary.txt, wb).write(b"1
2
3
")和open(text.txt, w).write("1
2
3
")并尝试在notepad.exe中打开这两个文件
因为notepad.exe太笨了以至于无法识别 n作为换行符,当它没有前面时 r n对我来说不是一个很好的理由...如果我写" n"我希望该文件只包含 n。 ..
通过在非Posix环境(如MSDOS和MS Windows)上使用t,
序列在输入时转换为(在输出上转换为相反的)。 b(二进制模式)不执行此类转换。
据推测,CSV库处理回车(可能在遇到它们时忽略它们)。
编辑:刚刚注意到一个改变的问题。
由于.CSV文件并非真正供人类读者使用,因此库只能使用(换行(LF)又名换行)分隔符输出它们。他们唯一真正的缺点是MSWindows用户用记事本打开文件:它会显示不佳。 CSV库还可以输出带有
(CR LF)的文件,因为大多数程序都符合MSDOS文本文件约定。
无论哪种方式,库都可以通过b(二进制)模式编写。如果在t(文本)模式下打开,行分隔符可能会像
那样略微奇怪。可能大多数CSV文件解析器忽略CR,并将LF LF识别为结束一行并跟随一条空(空白)行,它也会忽略。
手册页中解释了+:
w+ Open for reading and writing. The file is created if it does
not exist, otherwise it is truncated. The stream is
positioned at the beginning of the file.
区别在于w+允许读写,而w只允许写入。
可能通过使用它们作为行分隔符()...但是很好的答案
是否在文本模式下翻译取决于平台(os.linesep)。它在Windows上。它不适用于OS X.您不需要显式使用t模式(它在Python 2上传递给stdio函数,因此它可以启用与平台相关的行为,例如将Ctrl + Z识别为输入上的EOF字符)。 csv模块始终在输入时识别 r和 n