TL; DR Использование unicode.decode
и str.encode
означает, что вы не используете правильные типы для представления своих данных. Методы в эквивалентных типах в Python 3 даже не существуют.
A unicode
значение представляет собой одну кодовую точку Unicode: целое число интерпретируется как особый персонаж. A str
, с другой стороны, представляет собой последовательность байтов.
Например, à
- это кодовая точка Unicode U + 00E0. Кодировка UTF-8 представляет его с помощью пары байтов, 0xC3 и 0xA0.
Метод unicode.encode
принимает строку Unicode (последовательность кодовых точек) и возвращает байтовый код. кодирование уровня каждой кодовой точки в виде одной строки байтов.
>>> ua.encode('utf-8')
'\xc3\xa0'
str.decode
принимает строку байтов и пытается создать эквивалентное значение Unicode.
>>> '\xc3\xa0'.decode('utf-8')
u'\xe0'
(u'\xe0'
эквивалентно u'à'
).
Что касается ваших ошибок: Python 2 не требует строгого разделения между использованием unicode
и str
. На самом деле не имеет смысла смысл кодировать str
, если это уже закодированное значение, и нет смысла декодировать значение unicode
, потому что оно не закодировано в первую очередь. Вместо того, чтобы точно определять, как происходят ошибки, я просто укажу, что в Python 3 есть два типа: bytes
- строка байтов (соответствует Python 2 str
) и str
является строкой Unicode (соответствует Python 2 unicode
). «Бессмысленные» методы даже не существуют в Python 3:
>>> bytes.encode
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'bytes' has no attribute 'encode'
>>> str.decode
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'str' has no attribute 'decode'
Так что ваши попытки, которые раньше вызывали Unicode*Error
исключений, просто подняли бы AttributeError
.
Если вы застряли с поддержкой Python 2, просто следуйте этим правилам:
unicode
для текст str
для двоичных данных unicode.encode
выдает str
значение str.decode
выдает unicode
значение - Если вы пытаетесь вызвать
str.encode
, вы используете неправильный тип. - Если вы пытаетесь позвонить
unicode.decode
, вы используете неправильный тип.