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

Введение В этой статье мы рассмотрим, как преобразовать байты в строку в Python. К концу этой статьи у вас будет четкое представление о том, что это за типы и как эффективно обрабатывать данные с их помощью. В зависимости от версии Python, которую вы используете, эта задача будет отличаться. Хотя Python 2 подошел к концу, он все еще используется во многих проектах, поэтому мы включим оба подхода - Python 2 и Python 3. Преобразование байтов в строку в Python 3 Начиная с Python 3, старый способ ASCII

Вступление

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

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus