質問: csv.writer(output, quoting=csv.QUOTE_NONNUMERIC) >>> writer.writerow(csvdata) 25 >>> output.getvalue() '1,"a","Whoa!\nNewlines!"\r\n' ``` なぜ `\ n` が1つしかないのですか?を `\ r \ n` に変換しましたか? > `\ n` 、 `\ r` 、または `\ r \ n コード> > 呼び出し元に返される前に `\ n` に変換されます。 > 逆に、*出力*で `\ n` はシステムのデフォルト行に変換されます > セパレータ、 `os.linesep` 。`
回答: "single" `\ n` は、第3フィールドのデータ文字として発生します。その結果、フィールドは引用され、csvリーダーはそれをデータの一部として扱います。これは "行終端文字"(行区切り記号と呼ばれる)またはその一部ではありません。クォートをよりよく理解するには、 `quoting = csv.QUOTE_NONNUMERIC` を削除してください。 csvはデフォルトで `\ r \ n` の `dialect.lineterminator` で行を終了するため、 `\ r \ n` が生成されます。つまり、 "universal newlines"設定は無視されます。 **Update** `io.StringIO` の2.7と3.2のドキュメントは、*改行* argに関する限り実質的に同じです。 > 改行引数はTextIOWrapperと同じように動作します。デフォルトは > 改行を行わないようにします。 > > 以下の最初の文を調べます。 "default"と "newline translation"の解釈に応じて、2番目の文は出力にtrueです。 TextIOWrapperドキュメント: > 改行はNone、 ''、 '\ n'、 '\ r'、 '\ r \ n'のいずれかです。それは > 行末の処理。 Noneの場合、ユニバーサル改行は > 有効になりました。これを有効にすると、入力時に '\ n'、 '\ r'、または > '\ r \ n'は、呼び出し元に返される前に '\ n'に変換されます。 > 逆に、出力では、 '\ n'はシステムのデフォルト行に変換されます > セパレータ、os.linesep。改行がその正当な値の他のものである場合、 > その改行は、ファイルが読み込まれたときに改行になります。 > 翻訳されずに返されます。出力時に、 '\ n'は改行に変換されます。 > > Windows上のPython 3.2: ``` >>> 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' >>> ``` Line 0 shows that the "default" that you get with no `newline` arg involves no translation of `\n` (or any other character). **It is certainly NOT converting `'\n'` to `os.linesep`** 行1は、 `newline = None` (行0と同じでなければなりませんか?)が有効であることを示しています。 *INPUT* 奇妙な! 行2: `'\ n'` を `"`に変換していないのは確かです。 3行目、4行目、5行目:ドキュメントが示すように、 `'\ n'` は `newline` argの値に変換されます。 同等のPython 2.Xコードは、Python 2.7.2で同等の結果をもたらします。 **Update 2** For consistency with built-in `open()`, the default should be `os.linesep`, as documented. To get the no-translation-on-output behaviour, use `newline=''`. Note: the `open()` docs are much clearer. I'll submit a bug report tomorrow.