В первом случае '\x85'.encode()
кодирует кодовую точку Unicode U + 0085 в кодировке по умолчанию для Python 3 UTF-8. Таким образом, на выходе получается правильное двухбайтовое кодирование UTF-8 этой кодовой точки:
>>> '\x85'.encode()
b'\xc2\x85'
Затем работает декодирование, поскольку оно было правильно закодировано в UTF-8 для начала:
>>> b'\xc2\x85'.decode()
'\x85'
Второй случай - это сложный способ создания однобайтовой строки:
>>> (0x85).to_bytes(1,'big')
b'\x85'
Эта байтовая строка неправильно закодирована как UTF-8, поэтому она не может быть декодирована:
>>> b'\x85'.decode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x85 in position 0: invalid start byte
Python 3 определенно не "сломан". Он четко отделяет байтовые данные от текста.
Если у вас есть необработанные байты, работайте с ними как с байтами. Необработанные данные в Python 3 предназначены для работы в байтовых строках или байтовых массивах. Строки Unicode предназначены для текста. Декодировать байты в текст, чтобы манипулировать им, затем кодировать обратно в байты для сериализации в файл, сокет, базу данных и т. Д.
Если по какой-то причине вы чувствуете необходимость использовать строки Unicode для необработанных данных, первые 256 кодовых точек Unicode соответствуют кодеку latin1
для преобразования 1: 1 одного в другой.
>>> '\x85'.encode('latin1')
b'\x85'
>>> b'\x85'.decode('latin1')
'\x85'
Это часто используется для исправления ошибок программирования из-за кодирования / декодирования с неправильными кодировками.