UnicodeDecodeError: кодек ascii не может декодировать байт 0xc3 в позиции 0: порядковый номер не в диапазоне (128)
Вы видели это исключение? Если вы знаете почему, можете пропустить это введение. Есть несколько замечательных статей и рассказов о Unicode и кодировании в Python, но я попытаюсь обобщить основные концепции.
При работе со строками в Python вы должны знать, с каким типом строки вы работаете. В Python 3 все немного изменилось, поэтому сначала мы сосредоточимся на Python 2.
Короче говоря, у вас могут быть строки как объекты BYTES или UNICODE, и вы должны это учитывать.
Юникод - это мировой стандарт для представления всех возможных представлений символов, в которых каждый имеет уникальный кодовый момент. Вот стол.
Например, кодовая точка π (pi) - это U + 03C0. В Python мы можем представлять объекты Unicode, добавляя u к нашей строке, и напрямую вызывать кодовые точки, добавляя \ u к ее кодовому номеру.
>>> print u'\u03c0 is pi!' π is pi!
Строки Unicode могут быть закодированы в байтовые строки с использованием различных кодировок, таких как ASCII или предпочтительно UTF-8.
Точно так же байтовые строки могут быть декодированы в объекты Unicode.
Если у вас есть байтовая строка в кодировке UTF-8, вы должны использовать UTF-8 для ее декодирования в объект Unicode, иначе вы получите ошибки.
Давайте рассмотрим этот пример,
>>> u'Hello ' + 'world' >>> # Python 2 actually does: u'Hello ' + 'world'.decode('ascii') u'Hello world' >>> u'Hello ' + 'π' >>> # Python 2 actually does: u'Hello ' + 'π'.decode('ascii') Traceback (most recent call last): File “<stdin>”, line 1, in <module> UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xcf in position 0: ordinal not in range(128)
Бум! Мы попытались объединить объект Unicode с байтовой строкой. Python 2 выполняет неявное декодирование для создания одного объекта Unicode, но его кодек по умолчанию - ASCII (для проверки можно запустить sys.getdefaultencoding ()). Итак, в первом примере «world» не было проблемой, но «π» не может быть декодировано с использованием ASCII.
Кодек - это ярлык для кодировщика / декодера.
>>> content = '\xcf\x80-zza'.decode('utf-8') # π-zza >>> type(content) <type 'unicode'> >>> print content π-zza >>> output_string = content.encode('utf-8') >>> type(output_string) <type 'str'> >>> output_string '\xcf\x80-zza' # bytes!
В заключение, файлы хранят байтовые строки, затем мы декодируем эти строки, используя соответствующий декодер (например, UTF-8, ASCII и т. Д.), В объекты Unicode для работы, и в самом конце, то есть перед записью в файл, кодируем наши строки с желаемым кодировщиком (например, UTF-8, ASCII и т. д.).
—
Так что пока все! В следующем посте я мог бы объяснить различия в представлении строк в Python 3, но если вам все еще интересно, я настоятельно рекомендую эти два других выступления по этой теме.
Нед Батчелдер: прагматичный Unicode
Entendiendo Unicode - Факундо Батиста - PyConAr 2012