Вступление
В этой статье мы рассмотрим, как преобразовать байты в строку в Python . К концу этой статьи у вас будет четкое представление о том, что это за типы и как эффективно обрабатывать данные с их помощью.
В зависимости от версии Python, которую вы используете, эта задача будет отличаться. Хотя Python 2 подошел к концу, он все еще используется во многих проектах, поэтому мы включим оба подхода - Python 2 и Python 3.
Преобразование байтов в строку в Python 3
Начиная с Python 3, старый способ работы с ASCII пришлось отказаться, и Python стал полностью Unicode.
Это означает, что мы потеряли явный тип Unicode: u"string"
- каждая
строка является u"string"
!
Чтобы отличить эти строки от старых добрых строк байтов, мы
познакомились с новым спецификатором для них - b"string"
.
Это было добавлено в Python 2.6, но не служило реальной цели, кроме подготовки к Python 3, поскольку все строки в 2.6 были строками байтов.
Строки байтов в Python 3 официально называются bytes
, неизменной
последовательностью целых чисел в диапазоне 0 <= x <256 . Еще один
bytes
-как объект , добавленный в версии 2.6 является bytearray
-
похож на bytes
, но изменяемый.
Преобразование байтов в строку с помощью decode ()
Давайте посмотрим, как мы можем преобразовать байты в String, используя
встроенный метод decode()
для класса bytes
>>> b = b"Lets grab a \xf0\x9f\x8d\x95!"
# Let's check the type
>>> type(b)
<class 'bytes'>
# 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 🍕!"
На самом деле вам не нужно передавать параметр кодировки, однако рекомендуется передавать его:
>>> 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 набор байтов и строка - это практически одно и то же: строки
- это объекты, состоящие из однобайтовых символов, что означает, что каждый символ может хранить 256 значений. Вот почему их иногда называют строками байтов .
Это замечательно при работе с байтовыми данными - мы просто загружаем их в переменную и готовы к печати:
>>> s = "Hello world!"
>>> s
'Hello world!'
>>> len(s)
12
Однако использование символов Unicode в строках байтов немного меняет это поведение:
>>> 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?
Преобразование байтов в Unicode (Python 2)
Здесь нам придется использовать Unicode
Python 2, который
предполагается и автоматически используется в 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
перед значением байтовой строки.
Итак, как мне переключаться между ними?
Вы можете получить строку Unicode, расшифровав свою байтовую строку. Это
можно сделать, создав объект Unicode, предоставив байтовую строку и
строку, содержащую имя кодировки в качестве аргументов, или вызвав
.decode(encoding)
для байтовой строки.
Преобразование байтов в строку с помощью 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, в качестве повседневного драйвера.
Такие вещи, как кодировки , кодировки и двоичные файлы, напоминают нам, что наша работа - кодировать - кодировать наши мысли в рабочие решения. К счастью, многие из этих мыслей становятся частью нашей рутины после нескольких раундов за клавиатурой.
В этой статье мы рассмотрели, как преобразовать байты в строки в Python .