1. ホーム
  2. python

[解決済み] CSVへの書き込みで、空白文字列に「Error: need to escape」と表示される。

2022-02-02 16:29:01

質問

しかし、単純なエラーのように見えるものを打ち負かすことができないでいる自分に気がつきました。

PythonでCSVにデータを書き込んでいるところです。書きたいものの1つに list の整数値です。I join を文字列に変換してからファイルに書き込む。

with open('publishers.csv', 'wb') as f:
    writer = csv.writer(f, quoting=csv.QUOTE_NONE, delimiter='|', quotechar='')
    for item in big_list_of_objects:
        description = item.description
        number_list = item.number_list
        formatted_numbers = "-".join(number_list)
        writer.writerow([
            description,
            formatted_numbers
            ])

number_list には、0から大量の数字が入っていることがあります。もしそれが空のリストであれば join を設定するだけです。 formatted_numbers は空白の文字列と等しくなります。空リストでない場合は、ハイフンでつながれた整数からなる文字列が得られます。

number_list = [1,2,34,12]
formatted_numbers = '1-2-34-12'

number_list = []
formatted_numbers = ''

とにかくそういうことです。実際には、最初の5行が正常に書き込まれた後、次のようなことが起こります。

File "<console>", line 1, in <module>
  File "/path/path/path.py", line 500, in offending_function
    formatted_numbers
Error: need to escape, but no escapechar set

さて、この特定の状況では、書き込みに成功した最初の5行は、空の number_list . 一貫してクラッシュする行は には、空の number_list . の直前や直後に値が書かれていても、何もおかしなことはありません。 number_list をこの行に追加します。また formatted_numbers このエラーが発生したときに書かれている - 私は、このエラーが発生したときに print ステートメントが表示され、その前の5つのステートメントと同じように空文字列になっています。

どなたか、どこで間違っているのか、教えていただけませんか?


編集:これらのprintステートメントを追加しました。

with open('publishers.csv', 'wb') as f:
    writer = csv.writer(f, quoting=csv.QUOTE_NONE, delimiter='|', quotechar='')
    for item in big_list_of_objects:
        description = item.description
        print "Description for %r is %r" % (item,description)
        number_list = item.number_list
        print "Now formatting %r for %r" % (number_list,item)
        formatted_numbers = "-".join(number_list)
        print repr(formatted_numbers)
        writer.writerow([
            description,
            formatted_numbers
            ])

その結果

Description for 'p89' is u''
Now formatting '' for 'p89'
''
Description for 'p88' is u''
Now formatting '' for 'p88'
''
Description for 'p83' is u''
Now formatting '' for 'p83'
''
Description for 'p82' is u'in-tr-t91411'
Now formatting '' for 'p82'
''
Description for 'p81' is u''
Now formatting '' for 'p81'
''
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/path/path/path.py", line 501, in offending_function
    formatted_numbers
Error: need to escape, but no escapechar set

p81 がCSVに書き込まれない - ここでクラッシュが発生します。しかし、ご覧のように print repr(formatted_numbers) は、その前の文字列と同じ空白文字列であることがわかります。また description アイテム p81 (単なる空白文字列)が、そこに a description は、その前の項目に対するものです。

解決方法は?

この問題が発生するのは、おそらく description| が入っていますが、これはcsvのデリミタでもあります。したがって、csvはこれをエスケープしようとしますが csv.escapechar が設定されています。私のコンピュータで同じ問題を表示する例

>>> description = 'asda|sd'
>>> formatted_numbers = ''
>>> with open('a.csv','w') as f:
...     writer = csv.writer(f, quoting=csv.QUOTE_NONE, delimiter='|', quotechar='')
...     writer.writerow([
...             description,
...             formatted_numbers
...             ])
...
Traceback (most recent call last):
  File "<stdin>", line 5, in <module>
_csv.Error: need to escape, but no escapechar set

修正方法としては、escapecharを用意して、エスケープできるようにすることでしょう。例

writer = csv.writer(f, quoting=csv.QUOTE_NONE, delimiter='|', quotechar='',escapechar='\\')    #Or any other appropriate escapechar

あるいは、別の修正として | を記述する必要がないのであれば、記述する前に

description = description.replace('|','')

また、すべてのフィールドを引用することもできます。 csv.QUOTE_ALL の代わりに csv.QUOTE_NONE を指定すると、有効な quotechar .