Как исправить: «unicodedecodeerror: кодек ascii не может декодировать байт»

Unicode Zen в Python 2.x — длинная версия

Не видя источника, трудно понять причину, поэтому мне придется говорить в целом.

обычно происходит, когда вы пытаетесь преобразовать Python 2.x , который не является ASCII, в строку Unicode без указания кодировки исходной строки.

Вкратце, строки Unicode — это совершенно отдельный тип строки Python, которая не содержит никакой кодировки. Они содержат только коды точек Unicode и поэтому могут содержать любую точку Unicode по всему спектру. Строки содержат кодированный текст, beit UTF-8, UTF-16, ISO-8895-1, GBK, Big5 и т.д. Строки декодируются в Unicode и Юникоды кодируются в строки . Файлы и текстовые данные всегда передаются в закодированных строках.

Авторы модуля Markdown, вероятно, используют (где выбрасывается исключение) в качестве качественного шлюза для остальной части кода — он преобразует ASCII или переупорядочивает существующие строки Unicodes в новую строку Unicode. Авторы Markdown не могут знать кодировку входящей строки, поэтому будут полагаться на то, что вы декодируете строки в строки Unicode, прежде чем перейти к Markdown.

Строки Unicode могут быть объявлены в вашем коде с помощью префикса к строкам. Например.

Строки Unicode могут также поступать из файлов, баз данных и сетевых модулей. Когда это происходит, вам не нужно беспокоиться о кодировке.

Python 3

Python 3 не более Unicode способен, чем Python 2.x, однако он немного менее запутан в теме. Например, обычное теперь является строкой Unicode, а старое теперь .

По умолчанию используется кодировка UTF-8, поэтому, если вы байтовой строки не указали кодировку, Python 3 использует кодировку UTF-8. Это, вероятно, решает 50% проблем Unicode людей.

Кроме того, по умолчанию работает в текстовом режиме, поэтому возвращает декодированное (Unicode). Кодировка получена из вашей локали, которая имеет тенденцию быть UTF-8 в системах Un * x или 8-битной кодовой страницей, такой как windows-1251, в блоках Windows.

Example

Python 2.x2.7
“1deadbeef3″.decode(‘hex’)# Out: ‘x1dxeaxdbxeexf3”x1dxeaxdbxeexf3’.encode(‘hex’)# Out: 1deadbeef3

Python 3.x3.0
“1deadbeef3”.decode(‘hex’)# Traceback (most recent call last):# File “<stdin>”, line 1, in <module># AttributeError: ‘str’ object has no attribute ‘decode’b”1deadbeef3″.decode(‘hex’)# Traceback (most recent call last):# File “<stdin>”, line 1, in <module># LookupError: ‘hex’ is not a text encoding; use codecs.decode() to handle arbitrary codecs’x1dxeaxdbxeexf3′.encode(‘hex’)# Traceback (most recent call last):# File “<stdin>”, line 1, in <module># LookupError: ‘hex’ is not a text encoding; use codecs.encode() to handle arbitrary codecsb’x1dxeaxdbxeexf3′.encode(‘hex’)# Traceback (most recent call last):# File “<stdin>”, line 1, in <module># AttributeError: ‘bytes’ object has no attribute ‘encode’

However, as suggested by the error message, you can use the codecs module to achieve the same result:

import codecscodecs.decode(‘1deadbeef4’, ‘hex’)# Out: b’x1dxeaxdbxeexf4’codecs.encode(b’x1dxeaxdbxeexf4′, ‘hex’)# Out: b’1deadbeef4′

Note that codecs.encode returns a bytes object. To obtain a str object just decode to ASCII:

codecs.encode(b’x1dxeaxdbxeexff’, ‘hex’).decode(‘ascii’)# Out: ‘1deadbeeff’

Юникод сэндвич

Хорошей практикой является формирование сэндвича Unicode в вашем коде, где вы декодируете все входящие данные в строки Unicode, работаете с Unicodes, а затем кодируете в s на выходе. Это избавляет вас от беспокойства о кодировании строк в середине вашего кода.

Ввод/Декодирование

Исходный код

Если вам нужно добавить не-ASCII в ваш исходный код, просто создайте строки Unicode, добавив префикс . Например.

Чтобы позволить Python декодировать исходный код, вам необходимо добавить заголовок кодирования, соответствующий фактической кодировке вашего файла. Например, если ваш файл был закодирован как UTF-8, вы должны использовать:

Это необходимо только в том случае, если в исходном коде есть код (не = ASCII) .

Обычно не-ASCII данные получаются из файла. Модуль предоставляет TextWrapper, который декодирует ваш файл на лету, используя заданное . Вы должны использовать правильную кодировку для файла — это не может быть легко угадано. Например, для файла UTF-8:

Тогда будет подходящим для перехода к Markdown. Если из строки , то вы, вероятно, использовали неправильное значение кодировки.

Модуль Python 2.7 CSV не поддерживает символы не ASCII ????. Однако помощь под рукой: https://pypi.python.org/pypi/backports.csv .

Используйте его как выше, но передайте ему открытый файл:

Базы данных

Большинство драйверов баз данных Python могут возвращать данные в Unicode, но обычно требуют небольшой настройки. Всегда используйте строки Unicode для запросов SQL.

В строке подключения добавьте:

Например.

Добавлять:

HTTP

Веб-страницы могут быть закодированы практически в любой кодировке. Заголовок должен содержать поле для указания на кодировку. Затем содержимое может быть декодировано вручную в соответствии с этим значением. В качестве альтернативы Python-Requests возвращает Unicodes в .

Вручную

Если вам необходимо декодировать строки вручную, вы можете просто выполнить , где — подходящая кодировка. Python 2.x поддерживаемые кодеки приведены здесь: . Опять же, если вы получите , значит, вы, вероятно, ошиблись кодировкой.

Результат

стандартный вывод/печать

пишет через поток stdout. Python пытается настроить кодировщик на стандартный вывод, чтобы Unicodes кодировались в кодировку консоли. Например, если оболочки Linux — , выходные данные будут закодированы в . В Windows вы будете ограничены 8-битной кодовой страницей.

Неправильно настроенная консоль, например поврежденная локаль, может привести к неожиданным ошибкам печати. Переменная окружения может форсировать кодирование для stdout.

5 ответов

начните с Python 3, вся строка является объектом unicode.

a = ‘Happy New Year’ # Python 3 b = unicode(‘Happy New Year’) # Python 2

код перед тем же. Поэтому я думаю, что вы должны удалить .decode(‘utf-8’). Потому что вы уже получили объект unicode.

используйте его этим методом:

str.encode().decode()

Я не знаком с библиотекой, но если ваша проблема в том, что вам не нужен массив байтов, один простой способ-указать тип кодировки прямо в приведении:

>>> my_byte_strb’Hello World’>>> str(my_byte_str, ‘utf-8′)’Hello World’

Он уже декодирован в Python3, попробуйте напрямую, он должен работать.

Gotchas

Преобразование из в Unicode может происходить, даже если вы явно не вызываете .

Следующие сценарии вызывают исключения :

Примеры

На следующей диаграмме вы можете видеть, как Word был закодирован в кодировке UTF-8 или Cp1252 в зависимости от типа терминала. В обоих примерах — это просто обычная ascii. В UTF-8 код кодируется двумя байтами. В «Cp1252» é равно 0xE9 (что также является значением точки Unicode (это не совпадение)). Правильная вызывается, и преобразование в Python Юникод прошло успешно:

На этой диаграмме вызывается с (что аналогично вызову без заданной кодировки). Поскольку ASCII не может содержать байтов больше , это вызовет исключение :

Модель представления текста

Главное различие между Python 2 и Python 3 –базовые типы, существующие для работы со строками и байтовыми строками. В Python 3 мы имеем один строковый тип:

str

, который хранит данные в Unicode, и два байтовых типа:

bytes

и

bytearray

С другой стороны, в Python 2 у нас есть два строковых типа:

str

, который достаточен для любых целей и задач, ограниченных строками в кодировке ASCII + некоторыми неопределенными данными, превышающими интервал в 7 бит. Вместе с типом str у Python2 есть тип данных

unicode

, эквивалентный типу данных

str

Python 3. Для работы с байтами в Python 2 есть один тип:bytearray, взятый из Python 3. Присмотревшись к ситуации, вы можете заметить, что из Python 3 кое-что удалили: поддержку строковых данных не в юникоде.Компенсацией жертвоприношения стал хешируемый байтовый тип данных(

bytes

). Тип данных

bytarray

изменяемый, а поэтому он не может быть хеширован. Я очень редко, использую бинарные данные как ключи словаря, а потому возможность или невозможность хеширования бинарных данных не кажется мне очень серьезной. Особенно в Python 2, так как байты могут быть без каких-либо проблем помещены в переменную типа

str

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: