Устойчивая, реально работающая реализация CSV для не-ascii?

[Обновить] Цените ответы и вводите все со всех сторон, но рабочий код будет очень кстати. Если вы можете предоставить код, который может читать файлы примеров, вы король (или королева).

[Обновление 2] Спасибо за отличные ответы и обсуждение. Что мне нужно с ними сделать, так это прочитать их, проанализировать и сохранить их части в экземплярах модели Django. Я считаю, что это означает преобразование их из исходной кодировки в юникод, чтобы Django мог с ними справиться, верно?

Есть несколько вопросов по Stackoverflow уже по теме чтения CSV-файлов Python, отличных от ascii , но решения, показанные там и в документации на Python, не работают с входными файлами, которые я пытаюсь использовать.

Суть решения, похоже, заключается в кодировании ('utf-8') входных данных для считывателя CSV и unicode (item, 'utf-8') вывод читателя. Однако при этом возникают проблемы с UnicodeDecodeError (см. Вопросы выше):

UnicodeDecodeError: 'utf8' codec can't decode byte 0xa3 in position 8: unexpected

Входной файл не обязательно находится в utf8; это может быть ISO-8859-1, cp1251, или что-то еще.

Итак, вопрос: какой устойчивый способ с возможностью перекрестного кодирования читать файлы CSV в Python?

Корень проблемы, похоже, в том, что модуль CSV является расширением C; существует ли модуль чтения CSV на чистом питоне?

Если нет, есть ли способ с уверенностью определить кодировку входного файла, чтобы его можно было обработать?

В основном я ищу пуленепробиваемый способ читать (и, надеюсь, записывать) файлы CSV в любой кодировке.

Вот два примера файлов: Европейский , Русский .

И вот рекомендуемое решение не работает:

Python 2.6.4 (r264:75821M, Oct 27 2009, 19:48:32)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import csv
>>> def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
...     # csv.py doesn't do Unicode; encode temporarily as UTF-8:
...     csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
...                             dialect=dialect, **kwargs)
...     for row in csv_reader:
...         # decode UTF-8 back to Unicode, cell by cell:
...         yield [unicode(cell, 'utf-8') for cell in row]
...
>>> def utf_8_encoder(unicode_csv_data):
...     for line in unicode_csv_data:
...         yield line.encode('utf-8')
...
>>> r = unicode_csv_reader(file('sample-euro.csv').read().split('\n'))
>>> line = r.next()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 5, in unicode_csv_reader
  File "", line 3, in utf_8_encoder
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf8 in position 14: ordinal not in range(128)
>>> r = unicode_csv_reader(file('sample-russian.csv').read().split('\n'))
>>> line = r.next()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 5, in unicode_csv_reader
  File "", line 3, in utf_8_encoder
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 28: ordinal not in range(128)

13
задан Community 23 May 2017 в 11:54
поделиться