[Обновить] Оцените ответы и вводьте все вокруг, но рабочий код будет наиболее желанным. Если вы можете предоставить код, который может читать файлы примеров, которые вы являетесь королем (или королевой).
[Обновление 2] Спасибо за отличные ответы и обсуждения. Мне нужно сделать это, прочитать их, проанализировать и сохранить части из них в экземплярах модели Django. Я считаю, что это означает преобразование их из их родной кодировки в unicode, поэтому Django может справиться с ними, правильно?
Есть несколько questions в Stackoverflow уже на предмет чтения CSV-кода не-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 файлы в любой кодировке.
Вот два примера файлов: Европейский, Russian.
И здесь не рекомендованное решение:
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 "<stdin>", line 1, in <module>
File "<stdin>", line 5, in unicode_csv_reader
File "<stdin>", 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 "<stdin>", line 1, in <module>
File "<stdin>", line 5, in unicode_csv_reader
File "<stdin>", line 3, in utf_8_encoder
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 28: ordinal not in range(128)