Python: конвертировать Unicode в ASCII без ошибок для файла CSV - PullRequest
6 голосов
/ 10 января 2011

Я читал все вопросы, касающиеся преобразования из Unicode в CSV на Python здесь, в StackOverflow, и я все еще заблудился. Каждый раз, когда я получаю "кодек UnicodeEncodeError: 'ascii' не может кодировать символ u '\ xd1' в позиции 12: порядковый номер не в диапазоне (128)"

buffer=cStringIO.StringIO()
writer=csv.writer(buffer, csv.excel)
cr.execute(query, query_param)
while (1):
    row = cr.fetchone()
    writer.writerow([s.encode('ascii','ignore') for s in row])

Значение строки равно

(56, u"LIMPIADOR BA\xd1O 1'5 L")

, где значение \ xd10 в базе данных равно ñ, a n с диакритической тильдой, используемой на испанском языке. Сначала я пытался преобразовать значение во что-то действительное в ascii, но, потеряв так много времени, я пытаюсь игнорировать только эти символы (полагаю, у меня возникла бы та же проблема с ударными гласными).

Я хотел бы сохранить значение в CSV, желательно с символом - («LIMPIADOR BAÑO 1'5 L»), но если это невозможно, по крайней мере, можно сохранить его («LIMPIADOR BAO 1'5 L»). «).

1 Ответ

12 голосов
/ 10 января 2011

Правильно, ñ не является допустимым символом ASCII, поэтому его нельзя кодировать в ASCII. Таким образом, вы можете, как ваш код выше, игнорировать их. Другой способ, а именно убрать акценты, вы можете найти здесь: Каков наилучший способ удаления акцентов в строке Unicode Python?

Но учтите, что оба метода могут привести к плохим последствиям, например, когда слова на самом деле означают что-то другое и т. Д. Поэтому лучше всего сохранять акценты. И тогда вы не можете использовать ASCII, но вы можете использовать другую кодировку. UTF-8 - безопасная ставка. Латинская-1 или ISO-88591-1 является обычной, но она включает только западноевропейские символы. CP-1252 распространен в Windows и т. Д. И т. Д.

Так что просто переключите "ascii" для любой кодировки, которую вы хотите.


Ваш фактический код, согласно вашему комментарию:

writer.writerow([s.encode('utf8') if type(s) is unicode else s for s in row]) 

, где

row = (56, u"LIMPIADOR BA\xd1O 1'5 L")

Теперь, я считаю, что это должно работать, но, очевидно, это не так. Я думаю, что Unicode все равно передается в CvS Writer по ошибке. Разверните эту длинную строку по ее частям:

col1, col2 = row # Use the names of what is actually there instead
row = col1, col2.encode('utf8')
writer.writerow(row) 

Теперь ваша настоящая ошибка не будет скрыта тем фактом, что вы вставляете все в одну строку. Этого также, вероятно, можно было бы избежать, если бы вы включили правильную трассировку.

...