Запись файла.CSV в Python, который работает как для Python 2. 7+, так и для Python 3. 3+ в Windows

EDIT: Я сказал, что в названии, но просто понял, что я не упоминал об этом в теле. Это похоже на Windows.

Мне сложно записывать выходные данные, используя модуль csv Python в скрипте, который работает как с Python 2.7, так и с 3.3.

Первая попытка, которая работает как ожидается в Python 2.7:

with open('test.csv', 'wb') as csv_file:
    writer = csv.DictWriter(csv_file, ['header1', 'header2'])
    writer.writeheader()
    for item in items:
        writer.writerow(item)

Однако, когда то же самое выполняется в Python 3.3, вы заканчиваете:

TypeError: 'str' does not support the buffer interface

Поэтому я меняю 'wb' на 'wt' и он запускается, но теперь у меня есть лишняя строка в каждой строке в файле.

Чтобы исправить это, я меняю:

with open('test.csv', 'wt') as csv_file:

чтобы:

with open('test.csv', 'wt', newline='') as csv_file:

Но теперь он разбивает Python 2.7:

TypeError: 'newline' is an invalid keyword argument for this function

Я знаю, что могу просто сделать что-то вроде:

try:
    with open('test.csv', 'wt', newline='') as csv_file:
        writer = csv.DictWriter(csv_file, ['header1', 'header2'])
        writer.writeheader()
        for item in items:
            writer.writerow(item)
except TypeError:
    with open('test.csv', 'wb') as csv_file:
        writer = csv.DictWriter(csv_file, ['header1', 'header2'])
        writer.writeheader()
        for item in items:
            writer.writerow(item)

Тем не менее, это имеет серьезное плохое дублирование.

У кого-нибудь есть более чистый способ сделать это?

EDIT: тестовые данные просты и не имеют новой строки или чего-то еще:

items = [{'header1': 'value', 'header2': 'value2'},
         {'header1': 'blah1', 'header2': 'blah2'}]

Ответы

Ответ 1

Я пробовал несколько способов. Насколько я вижу, простым использованием 'w' может быть решение:

with open('test.csv', 'w') as csv_file:
    writer = csv.DictWriter(csv_file, fieldnames=['header1', 'header2'], lineterminator='\n')
    # write something

Ответ 2

Здесь более простой общий способ:

import sys

if sys.version_info[0] == 2:  # Not named on 2.6
    access = 'wb'
    kwargs = {}
else:
    access = 'wt'
    kwargs = {'newline':''}

with open('test.csv', access, **kwargs) as csv_file:
    writer = csv.DictWriter(csv_file, ['header1', 'header2'])
    writer.writeheader()
    for item in items:
        writer.writerow(item)

Принцип здесь заключается в том, чтобы не пытаться бороться с различиями между Python 2 и 3, но иметь условный код. До сих пор вы можете писать только код без такого теста, рано или поздно вам придется протестировать версию Python.