“单个”\n
作为第三个字段内的数据字符出现。因此,该字段被引用,以便csv读者将其视为数据的一部分。它不是“行终止符”(应该称为行分隔符)或其中的一部分。为了更好地理解报价,请删除quoting=csv.QUOTE_NONNUMERIC
。
生成\r\n
是因为csv终止行,其中dialect.lineterminator
的默认值为\r\n
。换句话说,“通用换行符”设置被忽略。
更新
2.7和3.2文档为io.StringIO
实际上是相同的,只要在换行符 ARG而言。
newline参数的工作方式与TextIOWrapper相同。默认值是 ,不进行换行。
我们将检查下面的第一句。第二句话对于输出是正确的,取决于你对“默认”和“换行译文”的解释。
TextIOWrapper文档:
换行符可以是无, '', '\ n', '\ r',或 '\ r \ N'。它控制 处理行尾。如果是None,则启用通用换行符 。启用此功能后,输入时,行结束符'\ n','\ r'或 '\ r \ n'在返回给调用者之前被转换为'\ n'。 相反,在输出时,'\ n'被转换为系统默认行 分隔符os.linesep。如果换行符是其合法值的任何其他值,则 换行时,换行变为换行符,并且 返回未翻译。在输出时,'\ n'被转换为换行符。
Python 3。2在Windows上:
>>> from io import StringIO as S
>>> import os
>>> print(repr(os.linesep))
'\r\n'
>>> ss = [S()] + [S(newline=nl) for nl in (None, '', '\n', '\r', '\r\n')]
>>> for x, s in enumerate(ss):
... m = s.write('foo\nbar\rzot\r\n')
... v = s.getvalue()
... print(x, m, len(v), repr(v))
...
0 13 13 'foo\nbar\rzot\r\n'
1 13 12 'foo\nbar\nzot\n'
2 13 13 'foo\nbar\rzot\r\n'
3 13 13 'foo\nbar\rzot\r\n'
4 13 13 'foo\rbar\rzot\r\r'
5 13 15 'foo\r\nbar\rzot\r\r\n'
>>>
0行显示该“默认”你没有newline
ARG得到不涉及的\n
翻译(或任何其他字符)。 这肯定是不转换'\n'
到os.linesep
行1显示了你有newline=None
得到(应该是一样的0线,应该不会吧?)实际上是INPUT通用换行符翻译 - 离奇!
第2行:newline=''
没有变化,像第0行。它当然不会将'\n'
转换为''
。
第3,4和5行:如文档所述,'\n'
转换为newline
arg的值。
等效的Python 2.X代码与Python 2.7.2产生相同的结果。
更新2对于内置open()
,默认应该是os.linesep
,如记录一致。要获得无输出转换行为,请使用newline=''
。注意:open()
文档更清晰。我明天提交一份错误报告。
非常感谢您的详细解释(和探索)。我想我在这里看着一个深渊。 – 2012-02-07 11:15:51
@TimPietzcker:等到你看*输入*。 – 2012-02-07 11:29:30