Python 2 и 3 CSV модуль текстово-двоичный режим обратной совместимости - PullRequest
0 голосов
/ 19 мая 2019

Я хотел бы создать код, совместимый с Python 2.7-3.6. Я пытаюсь исправить проблему с модулем csv, где изначально я использовал outfile=open('./test.csv','wb') в Python 2.7, теперь я должен использовать outfile=open('./test.csv','w') какв этом вопросе в противном случае я понесу TypeError: a bytes-like object is required, not 'str'.

A, как только я исправлю это с помощью этого кода:

import sys
w = 'w'
if sys.version_info[0] < 3:
   w = 'wb'
# Where needed
outfile=open('./test.csv',w)

Не очень приятно, есть ли что-нибудь лучше?решение для открытия файла в 'wb', если я использую Python 2.7 и в w, если я использую Python 3.x?Чтобы уточнить, я должен использовать wb в Python 2.7, потому что в противном случае у меня будет пустая строка каждый раз, когда я добавляю новую строку в файл.

1 Ответ

2 голосов
/ 19 мая 2019

При открытии файлов для использования с модулем csv на python 3 вам всегда следует добавить newline="" оператора open:

import sys
mode = 'w'
if sys.version_info[0] < 3:
   mode  = 'wb'

# python 3 write 
with open("somefile.txt", mode, newline="") as f:
    pass  # do something with f

Параметр newline не существует в python 2 - но если вы пропустите его в python 3 , вы получите неправильный вывод csv для окон с дополнительными пустыми строками.

См. csv.writer (python 3) :

Если csvfile является файловым объектом, его следует открыть с помощью newline=''.Если newline='' не указано, символы новой строки, встроенные в кавычки, не будут правильно интерпретироваться, и на платформах, которые используют \r\n строк при записи, будет добавлен дополнительный \r.Всегда должно быть безопасно указывать newline='', так как csv модуль выполняет свою собственную (универсальную) обработку новой строки.


Вы должны использовать контекстный менеджмент withа также:

with open("somefile.txt", mode) as f:  # works in 2 and 3
    pass  # do something with f

, чтобы закрыть дескрипторы файлов, даже если вы столкнулись с каким-то исключением.Это безопасно для Python 2 - см. Методы файловых объектов :

Рекомендуется использовать ключевое слово with при работе с объектами файла.Преимущество этого заключается в том, что файл правильно закрывается после завершения его набора, даже если по пути возникает исключение.Это также намного короче, чем написание эквивалентных try-finally блоков.


Ваше решение - некрасиво, но работает:

import sys
python3 = sys.version_info[0] >= 3 

if python3:
    with open("somefile.txt","w",newline="") as f:
        pass
else:
    with open("somefile.txt","wb") as f:
        pass

Проблема в параметре newline не существует в python 2. Чтобы исправить это, вам нужно будет обернуть / monkypath open(..), включая управление контекстом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...