Ответ 1
"single" \n
происходит как символ данных внутри третьего поля. Следовательно, это поле цитируется так, что csv-ридер будет рассматривать его как часть данных. Это НЕ "ограничитель строки" (следует называть разделителем строк) или его частью. Чтобы получить более высокую оценку цитирования, удалите quoting=csv.QUOTE_NONNUMERIC
.
\r\n
создается потому, что csv завершает строки с dialect.lineterminator
, по умолчанию \r\n
. Другими словами, параметр "универсальные новые строки" игнорируется.
Обновить
2.7 и 3.2 docs для io.StringIO
практически идентичны по отношению к аргументу newline.
Аргумент новой строки работает так же, как и TextIOWrapper. По умолчанию используется не выполнять перевод новой строки.
Мы рассмотрим первое предложение ниже. Второе предложение верно для вывода, в зависимости от вашей интерпретации "по умолчанию" и "перевода новой строки".
Документы TextIOWrapper:
newline может быть None, '', '\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
, не содержит перевода \n
(или любого другого символа). Это НЕ преобразование '\n'
в os.linesep
Строка 1 показывает, что то, что вы получаете с newline=None
(должно быть таким же, как строка 0, не так ли?) действует INPUT универсальный перевод новых строк - причудливый!
Строка 2: newline=''
не изменяет, как строка 0. Это, конечно, НЕ преобразует '\n'
в ''
.
Строки 3, 4 и 5: как говорят документы, '\n'
преобразуется в значение аргумента newline
.
Эквивалентный код Python 2.X дает эквивалентные результаты с помощью Python 2.7.2.
Обновление 2 Для согласования со встроенным open()
по умолчанию должно быть os.linesep
, как описано. Чтобы получить поведение без перевода, используйте newline=''
. Примечание. Документы open()
намного понятнее. Я отправлю отчет об ошибке завтра.