Запись в 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
.