web-dev-qa-db-ja.com

Pythonで.CSVファイルを書き込むことは、WindowsではPython 2.7+とPython 3.3+の両方で機能します

編集:私はそれをタイトルに入れましたが、私は本文でそれを言及していないことに気づきました。これはWindowsに固有のようです。

Python 2.7と3.3の両方で機能するスクリプトでcsv Pythonモジュールを使用して出力を書き込むのに苦労しています。

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'と実行されますが、ファイルの1行おきに余分な空白行があります。

それを修正するために、私は変更します:

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)

ただし、これには重大な重複があります。

誰かがこれを行うよりきれいな方法を持っていますか?

編集:テストデータはシンプルで、改行も何もありません:

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

私はいくつかの方法を試しました。私が見る限り、'w'は解決策かもしれません:

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

これはより簡単な一般的な方法です:

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バージョンをテストする必要があります。

8
cdarke