Строка байта и строка unicode. питон
Не могли бы вы подробно объяснить, какая разница между байтовой строкой и строкой Unicode в Python. Я прочитал this:
Байт-код - это просто преобразованный исходный код в массивы байтов
Означает ли это, что у Python есть собственный формат кодирования/кодирования? Или он использует настройки операционной системы?
Я не понимаю. Не могли бы вы объяснить?
Спасибо!
Ответы
Ответ 1
Ни один python не использует свою собственную кодировку. Он будет использовать любую кодировку, к которой он имеет доступ и который вы укажете. Символ в str
представляет один символ Юникода. Однако, чтобы представить более 256 символов, отдельные кодировки Unicode используют более одного байта на символ для представления многих символов. Объекты bytearray
предоставляют вам доступ к нижним байтам. str
объекты имеют метод encode
, который принимает строку, представляющую кодировку, и возвращает объект bytearray
, который представляет строку в этой кодировке. Объекты bytearray
имеют метод decode
, который принимает строку, представляющую кодировку, и возвращает str
, что является результатом интерпретации bytearray
как строки, закодированной в данной кодировке. Вот пример.
>>> a = "αά".encode('utf-8')
>>> a
b'\xce\xb1\xce\xac'
>>> a.decode('utf-8')
'αά'
Мы видим, что UTF-8 использует четыре байта, \xce,\xb1,\xce и\xac для представления двух символов. После статьи Spolsky, о которой упоминал Игнасио Васкес-Абрамс, я прочитал Python Unicode Howto.
Ответ 2
Вот попытка простого объяснения, которое применимо только к Python 3. Я надеюсь, что, если исходить от непрофессионала, это поможет устранить путаницу для совершенно непосвященных. Если есть какие-либо технические неточности, пожалуйста, простите меня и не стесняйтесь указывать на это.
Предположим, вы создаете строку с использованием Python 3 обычным способом:
stringobject = 'ant'
stringobject
будет stringobject
.
Строка Unicode состоит из символов Unicode. В stringobject
выше stringobject
являются отдельные буквы, например, a, n, t
Каждому символу Юникода присваивается кодовая точка, которая может быть выражена в виде последовательности шестнадцатеричных цифр (шестнадцатеричная цифра может принимать 16 значений в диапазоне от 0 до 9 и AF). Например, буква 'a'
эквивалентна '\u0061'
, а "муравей" эквивалентен '\u0061\u006E\u0074'
.
Таким образом, вы обнаружите, что если вы введете,
stringobject = '\u0061\u006E\u0074'
stringobject
Вы также получите вывод 'ant'
.
Теперь юникод преобразуется в байты в процессе, известном как кодирование. Обратный процесс преобразования байтов в Unicode известен как декодирование.
Как это сделать? Поскольку каждая шестнадцатеричная цифра может принимать 16 различных значений, она может быть отражена в 4-битной двоичной последовательности (например, шестнадцатеричная цифра 0 может быть выражена в двоичном виде как 0000, шестнадцатеричная цифра 1 может быть выражена как 0001 и так далее). Если символ Юникода имеет кодовую точку, состоящую из четырех шестнадцатеричных цифр, ему потребуется 16-битная двоичная последовательность для его кодирования.
Различные системы кодирования определяют разные правила для преобразования юникода в биты. Наиболее важно, что кодировки отличаются количеством битов, которые они используют для выражения каждого символа Юникода.
Например, система кодирования ASCII использует только 8 бит (1 байт) на символ. Таким образом, он может кодировать только символы Юникода с кодами длиной до двух шестнадцатеричных цифр (то есть 256 различных символов Юникода). Система кодирования UTF-8 использует от 8 до 32 бит (от 1 до 4 байтов) на символ, поэтому она может кодировать символы Юникода с кодовыми точками длиной до 8 шестнадцатеричных цифр, т.е. всем.
Выполнение следующего кода:
byteobject = stringobject.encode('utf-8')
byteobject, type(byteobject)
преобразует строку Unicode в строку байтов, используя систему кодирования utf-8, и возвращает b'ant', bytes'
.
Обратите внимание, что если бы вы использовали ASCII в качестве системы кодирования, вы не столкнулись бы с какими-либо проблемами, поскольку все кодовые точки в 'ant' могут быть выражены 1 байтом. Но если бы у вас была строка Unicode, содержащая символы с точками кода длиннее двух шестнадцатеричных цифр, вы получите UnicodeEncodeError
.
Так же,
stringobject = byteobject.decode('utf-8')
stringobject, type(stringobject)
дает тебе 'ant', str
.
Ответ 3
Для тех, кто хочет получить более подробное объяснение, просмотрите эту презентацию PyCon.