Рубрики
Без рубрики

Преобразование байтов в строку в Python

В этом уроке мы рассмотрим примеры преобразования байтов в строку в Python 2 и 3. Мы будем использовать функции decode (), str (), а также модуль codecs.

Автор оригинала: 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 .