Python byte string to str

Преобразование байтов в строку в 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

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

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

b = b"Lets grab a \xf0\x9f\x8d\x95!" # Let's check the type print(type(b)) # # Now, let's decode/convert them into a string s = b.decode('UTF-8') print(s) # "Let's grab a 🍕!" 

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

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

Как вариант, для этой цели мы можем использовать встроенный модуль 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 🍕!" 

Преобразование байтов в строку с помощью 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) у байтовой строки.

Преобразование байтов в строку с помощью 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') јч 

Исходное сообщение было либо, øç либо јч , и оба кажутся допустимыми преобразованиями.

Источник

Конвертация между байтами и строками#

Избежать работы с байтами нельзя. Например, при работе с сетью или файловой системой, чаще всего, результат возвращается в байтах.

Соответственно, надо знать, как выполнять преобразование байтов в строку и наоборот. Для этого и нужна кодировка.

Кодировку можно представлять как ключ шифрования, который указывает:

  • как «зашифровать» строку в байты (str -> bytes). Используется метод encode (похож на encrypt)
  • как «расшифровать» байты в строку (bytes -> str). Используется метод decode (похож на decrypt)

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

encode, decode#

Для преобразования строки в байты используется метод encode:

In [1]: hi = 'привет' In [2]: hi.encode('utf-8') Out[2]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [3]: hi_bytes = hi.encode('utf-8') 

Чтобы получить строку из байт, используется метод decode:

In [4]: hi_bytes Out[4]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [5]: hi_bytes.decode('utf-8') Out[5]: 'привет' 

str.encode, bytes.decode#

Метод encode есть также в классе str (как и другие методы работы со строками):

In [6]: hi Out[6]: 'привет' In [7]: str.encode(hi, encoding='utf-8') Out[7]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' 

А метод decode есть у класса bytes (как и другие методы):

In [8]: hi_bytes Out[8]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [9]: bytes.decode(hi_bytes, encoding='utf-8') Out[9]: 'привет' 

В этих методах кодировка может указываться как ключевой аргумент (примеры выше) или как позиционный:

In [10]: hi_bytes Out[10]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [11]: bytes.decode(hi_bytes, 'utf-8') Out[11]: 'привет' 

Как работать с Юникодом и байтами#

Есть очень простое правило, придерживаясь которого, можно избежать, как минимум, части проблем. Оно называется «Юникод-сэндвич»:

  • байты, которые программа считывает, надо как можно раньше преобразовать в Юникод (строку)
  • внутри программы работать с Юникод
  • Юникод надо преобразовать в байты как можно позже, перед передачей

Источник

Читайте также:  Php для web практика
Оцените статью