「單個」\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