Запись в CSV, получение "Ошибка: необходимость выхода" для пустой строки

Я, вероятно, буду чувствовать себя очень глупым, когда кто-то видит то, что я делаю неправильно здесь, но я не могу победить то, что похоже, это должна быть простая ошибка.

Я пишу некоторые данные в CSV с Python. Одна из вещей, которую я хочу написать, - это list целых чисел. я 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 может иметь от нуля до целой группы чисел. Если это пустой список, join просто устанавливает formatted_numbers равным пустой строке. Если это не пустой список, я получаю строку, состоящую из целых чисел, связанных дефисом.

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

number_list = []
formatted_numbers = ''

Это идея, во всяком случае. В действительности, то, что происходит, это первые пять строк, которые записываются успешно, и я получаю:

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

Теперь в этой конкретной ситуации первые пять строк, которые успешно записываются, имеют пустой number_list. Строка, которая последовательно выходит из строя, также имеет пустой number_list. Нет ничего странного в том, что значение записывается непосредственно перед или после number_list в этой строке. И нет ничего странного в том, что formatted_numbers записывается при возникновении этой ошибки - я перебросил в оператор 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) показывает, что это пустая строка, идентичная тем, которые были перед ней. Для элемента p81 (просто пустая строка) нет description, но для элемента, предшествующего ему, есть description.

Ответы

Ответ 1

Вероятно, проблема связана с тем, что в вашем description есть |, что является разделителем для вашего csv. Следовательно, csv пытается избежать этого, но не может, поскольку no 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.