DevGang
Авторизоваться

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

В этой статье мы рассмотрим, как преобразовать байты в строку в 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, но изменяемый.

Преобразование байтов в строку с помощью&nbsp;decode()

Давайте посмотрим, как мы можем преобразовать байты в String, используя встроенный метод decode() для класса bytes:

b = b"Lets grab a \xf0\x9f\x8d\x95!"
# Let's check the type
print(type(b))
# <class 'bytes'>

# Now, let's decode/convert them into a string
s = b.decode('UTF-8')
print(s)
# "Let's grab a 🍕!"

Передав формат кодирования, мы преобразовали объект bytes в строку и распечатали ее.

Преобразование байтов в строку с&nbsp;кодеками

Как вариант, для этой цели мы можем использовать встроенный модуль codecs:

import codecs

b = b'Lets grab a \xf0\x9f\x8d\x95!'
print(codecs.decode(b, 'UTF-8'))
# "Let's grab a 🍕!"

Вам действительно не нужно передавать параметр кодировки, однако рекомендуется передавать его:

print(codecs.decode(b))
# "Let's grab a 🍕!"

Преобразование байтов в строку с помощью&nbsp;str()

Наконец, вы можете использовать str()функцию, которая принимает различные значения и преобразует их в строки:

b = b'Lets grab a \xf0\x9f\x8d\x95!'
print(str(b, 'UTF-8'))
# "Let's grab a 🍕!"

Не забудьте указать аргумент кодировки str(), иначе вы можете получить неожиданные результаты:

print(str(b))
# b'Lets grab a \xf0\x9f\x8d\x95!'

Это снова подводит нас к кодировкам. Если вы укажете неправильную кодировку, в лучшем случае произойдет сбой вашей программы, потому что она не может декодировать данные. Например, если бы мы попытались использовать функцию str() с UTF-16, нас бы встретили:

print(str(b, 'UTF-16'))
# '敌❴\u2073牧扡愠\uf020趟↕'

Это даже более важно, учитывая, что Python 3 любит использовать Unicode, поэтому, если вы работаете с файлами или источниками данных, которые используют непонятную кодировку, обязательно обратите на это особое внимание.

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

В Python 2 набор байтов и строка - это практически одно и то же: строки - это объекты, состоящие из однобайтовых символов, что означает, что каждый символ может хранить 256 значений. Вот почему их иногда называют строками байтов.

Это замечательно при работе с байтовыми данными - мы просто загружаем их в переменную и готовы к печати:

s = "Hello world!"

print(s)
# 'Hello world!'

print(len(s))
# 12

Однако использование символов Unicode в строках байтов немного меняет это поведение:

s = "Let's grab a 🍕!"

print(s)
# 'Lets grab a \xf0\x9f\x8d\x95!'
# Where has the pizza gone to?

print(len(s))
# 17
# Shouldn't that be 15?

Преобразование байтов в Unicode (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 перед значением байтовой строки.

Итак, как мне переключаться между ними?

Вы можете получить строку Unicode, расшифровав свою байтовую строку. Это можно сделать, создав объект Unicode, предоставив байтовую строку и строку, содержащую имя кодировки в качестве аргументов, или вызвав .decode(encoding) у байтовой строки.

Преобразование байтов в строку с помощью&nbsp;decode()&nbsp;(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 🍕!"

Преобразование байтов в строку с помощью&nbsp;кодеков&nbsp;(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
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу