Наиболее значительное изменение в возможностях Python 3 это более
ясное разделение между текстовыми и двоичными данными. Текст это всегда
Unicode и представляется типом str, а двоичные данные представляются
типом bytes. Что делает это разделение особенно ясным так это то, что
str и bytes не могут смешиваться в языке Python 3 никаким явным
способом. Вы не можете сцеплять их, искать один тип внутри другого, и
как правило не можете передавать в функцию как аргумент один тип вместо
ожидаемого другого. Это хорошая новость
Кроме того, границы между строками и байтами преодолеваются только
через специальные функции, вот эту диаграмму всегда полезно держать в
памяти:
Строки могут быть закодированы в байты, а байты могут быть декодированы обратно в строки.
>>> '€20'.encode('utf-8')
b'\xe2\x82\xac20'
>>> b'\xe2\x82\xac20'.decode('utf-8')
'€20'
Думайте следующим образом: строка это абстрактное представление
текста. Строка содержит символы, которые являются абстрактными
элементами и не надо пытаться представить их в двоичном виде. При
манипулировании строками, мы остаемся в блаженное неведении о реальных
процессах. Мы можем разделить и порезать их, объединить их или устроить
поиск. Мы не должны волноваться о том как строки представлены внутри и
сколько байт нужно для представления символов. Мы начинаем задумываться
об этом когда кодируем строки в байты (например, для того чтобы послать
их через канал связи) или декодируем строки из байтов.
Аргументом для кодирования и декодирования является кодировка (или
кодек). Кодировка это способ представить абстрактные символы в виде
двоичных данных. Существует много возможных кодировок. UTF-8, показанная
здесь, это одна из них. А вот другая:
>>> '€20'.encode('iso-8859-15')
b'\xa420'
>>> b'\xa420'.decode('iso-8859-15')
'€20'
Кодирование является важной частью этого процесса перевода. Без
кодирования объект байтов b'\xa420' представляет собой всего лишь кучу
бит. Кодировка дает ему смысл. Используя другую кодировку, эта куча бит
может иметь другое значение:
>>> b'\xa420'.decode('windows-1255')
'₪20'
Так как восемьдесят процентов потерянных усилий происходит из за неправильной кодировки, будьте осторожней;-)