Python 2 CSV Writer создает неправильный терминатор строки в Windows

В соответствии с его документацией csv.writer должен использовать '\r\n' в качестве ограничителя строки по умолчанию.

import csv

with open("test.csv", "w") as f:
    writer = csv.writer(f)

    rows = [(0,1,2,3,4),
           (-0,-1,-2,-3,-4),
           ("a","b","c","d","e"),
           ("A","B","C","D","E")]           

    print writer.dialect.lineterminator.replace("\r", "\\r").replace("\n", "\\n")
    writer.writerows(rows)
    print writer.dialect.lineterminator.replace("\r", "\\r").replace("\n", "\\n")

Это печатает

\r\n
\r\n

как и ожидалось. Но созданный csv-файл использует терминатор строки '\r\r\n'

0,1,2,3,4

0,-1,-2,-3,-4

a,b,c,d,e

A,B,C,D,E

Это ошибка или что-то не так в моем использовании csv.writer?

Версия Python:

ActivePython 2.6.2.2 (ActiveState Software Inc.) на основе Python 2.6.2 (r262:71600, 21 апреля 2009, 15:05:37) [MSC v.1500 32 бит (Intel)] на win32

в Windows Vista

3 ответа

Решение

В Python 2.x всегда открывайте свой файл в двоичном режиме, как описано в документации. csv пишет \r\n как вы и ожидали, но затем механизм основного текстового файла Windows включается и изменяет \n в \r\n... общий эффект: \r\r\n

От csv.writer документация:

Если csvfile является файловым объектом, его необходимо открыть с помощью 'b' флаг на платформах, где это имеет значение.

Кажется, есть некоторая сдержанность в фактическом произнесении имени главного виновника:-)

Редактировать: Как упомянуто @jebob в комментариях к этому ответу и основано на ответе @Dave Burton, чтобы обработать этот случай в Python 2 и 3, вы должны сделать следующее:

if sys.version_info >= (3,0,0):
    f = open(filename, 'w', newline='')
else:
    f = open(filename, 'wb')

К сожалению, с модулем csv для Python 3 все немного по-другому, но этот код будет работать как на Python 2, так и на Python 3:

if sys.version_info >= (3,0,0):
    f = open(filename, 'w', newline='')
else:
    f = open(filename, 'wb')

Чтобы изменить терминатор строки в Python 2.7 CSV Writer используйте

writer = csv.writer(f, delimiter = '|', lineterminator='\n')

Это гораздо более простой способ изменить разделитель по умолчанию с \r\n.

Другие вопросы по тегам