Автор оригинала: Guest Contributor.
Преобразование байтов в строку в Python
Вступление
В этой статье мы рассмотрим как преобразовать байты в строку в Python . К концу этой статьи у вас будет четкое представление о том, что это за типы и как эффективно обрабатывать данные с их помощью.
В зависимости от версии Python, которую вы используете, эта задача будет отличаться. Хотя Python 2 подошел к концу своей жизни, многие проекты все еще используют его, поэтому мы включим в него как подходы Python 2, так и Python 3.
Преобразование байтов в строку в Python 3
Начиная с Python 3, старый способ ASCII должен был уйти, и Python стал полностью Unicode.
Это означает, что мы потеряли явный тип unicode: u"string"
– каждая строка является u"string"
!
Чтобы отличить эти строки от старых добрых bytestrings, мы вводим для них новый спецификатор – b"string"
.
Это было добавлено в Python 2.6, но оно не служило никакой реальной цели, кроме подготовки к Python 3, поскольку все строки были байт-строками в 2.6.
Байтовые строки в Python 3 официально называются bytes
, неизменяемая последовательность целых чисел в диапазоне 0 < 256 . Еще один bytes
-подобный объект, добавленный в 2.6, – это bytearray
– похожий на bytes
, но изменяемый.
Преобразование байтов в строку с помощью декодирования()
Давайте посмотрим, как мы можем преобразовать байты в строку, используя встроенный метод decode()
для класса bytes
:
>>> b = b"Lets grab a \xf0\x9f\x8d\x95!" # Let's check the type >>> type(b)# Now, let's decode/convert them into a string >>> s = b.decode('UTF-8') >>> s "Let's grab a 🍕!"
Передав формат кодировки, мы декодировали объект bytes
в строку и напечатали ее.
Преобразование байтов в строку с помощью кодеков
В качестве альтернативы мы также можем использовать встроенный модуль codecs
для этой цели:
>>> import codecs >>> b = b'Lets grab a \xf0\x9f\x8d\x95!' >>> codecs.decode(b, 'UTF-8') "Let's grab a 🍕!"
На самом деле вам не нужно | передавать параметр encoding, хотя рекомендуется передать его:
>>> codecs.decode(b) "Let's grab a 🍕!"
Преобразование байтов в строку с помощью str()
Наконец, вы можете использовать функцию str ()
, которая принимает различные значения и преобразует их в строки:
>>> b = b'Lets grab a \xf0\x9f\x8d\x95!' >>> str(b, 'UTF-8') "Let's grab a 🍕!"
Однако обязательно укажите аргумент кодировки в str ()
, иначе вы можете получить неожиданные результаты:
>>> str(b) b'Lets grab a \xf0\x9f\x8d\x95!'
Это снова подводит нас к кодировкам. Если вы укажете неверную кодировку, то в лучшем случае ваша программа выйдет из строя, потому что не сможет декодировать данные. Например, если мы попытаемся использовать функцию str()
с UTF-16
, нас встретят:
>>> str(b, 'UTF-16') '敌❴\u2073牧扡愠\uf020趟↕'
Это еще более важно, учитывая, что Python 3 любит принимать Unicode – поэтому, если вы работаете с файлами или источниками данных, использующими неясную кодировку, обязательно обратите на это особое внимание.
Преобразование байтов в строку в Python 2
В Python 2 связка байтов и строка – это практически одно и то же: строки-это объекты, состоящие из символов длиной в 1 байт, что означает, что каждый символ может хранить 256 значений. Вот почему их иногда называют байтовыми строками .
Это здорово при работе с байтовыми данными – мы просто загружаем их в переменную и готовы к печати:
>>> s = "Hello world!" >>> s 'Hello world!' >>> len(s) 12
Однако использование символов Юникода в байтовых строках немного меняет это поведение:
>>> s = "Let's grab a 🍕!" >>> s 'Lets grab a \xf0\x9f\x8d\x95!' # Where has the pizza gone to? >>> len(s) 17 # Shouldn't that be 15?
Преобразование байтов в Юникод (Python 2)
Здесь нам придется использовать тип Python 2 Unicode
, который предполагается и автоматически используется в Python 3. При этом строки хранятся в виде последовательности кодовых точек, а не байтов.
\xf0\x9f\x8d\x95
представляет байты в виде двузначных шестнадцатеричных чисел, поскольку Python не знает, как представить их в виде символов ASCII:
>>> u = u"Let's grab a 🍕!" u"Let's grab a \U0001f355!"" >>> u "Let's grab a 🍕!" # Yum. >>> len(u) 15
Как вы можете видеть выше, строка Unicode содержит \U0001f355
– экранированный символ Unicode, который ваш терминал теперь знает, как распечатать в виде ломтика пиццы! Установить это было так же просто, как использовать спецификатор u
перед значением bytestring.
Итак, как мне переключиться между ними?
Вы можете получить строку Unicode, декодировав свой bytestring. Это можно сделать, построив объект Unicode, предоставив bytestring и строку, содержащую имя кодировки в качестве аргументов, или вызвав .decode(encoding)
на bytestring.
Преобразование байтов в строку С помощью Функции decode() (Python 2)
Вы также можете использовать codecs.encode(s, encoding)
из модуля codecs
.
>>> s = "Let's grab a \xf0\x9f\x8d\x95!" >>> u = unicode(s, 'UTF-8') >>> u "Let's grab a 🍕!" >>> s.decode('UTF-8') "Let's grab a 🍕!"
Преобразование байтов в строку с помощью кодеков (Python 2)
Или с помощью модуля codecs
:
import codecs >>> codecs.decode(s, 'UTF-8') "Let's grab a 🍕!"
Будьте внимательны к своей кодировке
Слово предостережения здесь – байты могут быть интерпретированы по-разному в разных кодировках. С окружающим 80 различные кодировки доступны из коробки, это может быть не так просто узнать, если у вас есть правильный!
s = '\xf8\xe7' # This one will let us know we used the wrong encoding >>> s.decode('UTF-8') UnicodeDecodeError: 'utf8' codec can't decode byte 0xf8 in position 0: invalid start byte # These two overlaps and this is a valid string in both >>> s.decode('latin1') øç s.decode('iso8859_5') јч
Исходное сообщение было либо øç
, либо јч
, и оба они, по-видимому, являются действительными преобразованиями.
Вывод
Как программисты, есть некоторые вещи, о которых мы должны постоянно думать и активно готовиться, чтобы избежать ловушек. Это особенно верно на более низких уровнях, куда мы редко заходим, когда используем язык высокого уровня, такой как Python, в качестве нашего ежедневного драйвера.
Такие вещи, как charsets , encodings и binary существуют, чтобы напомнить нам, что наша работа состоит в том, чтобы code – кодировать наши мысли в рабочие решения. К счастью, многие из этих мыслей становятся частью нашей рутины после нескольких раундов за клавиатурой.
В этой статье мы рассмотрели как преобразовать байты в строки в Python .