Вопрос-Ответ

Best way to convert string to bytes in Python 3? [closed]

Лучший способ преобразовать строку в байты в Python 3?

Ошибка типа: 'str' не поддерживает интерфейс буфера предлагает два возможных метода преобразования строки в байты:

b = bytes(mystring, 'utf-8')

b = mystring.encode('utf-8')

Какой метод более питонический?


Смотрите, как преобразовать байты в строку, чтобы узнать об обратном способе.

Переведено автоматически
Ответ 1

Если вы посмотрите документы для bytes, это укажет вам на bytearray:


bytearray([источник[, кодировка [, ошибки]]])


Возвращает новый массив байтов. Тип bytearray представляет собой изменяемую последовательность целых чисел в диапазоне 0 <= x < 256. В нем есть большинство обычных методов изменяемых последовательностей, описанных в разделе Типы изменяемых последовательностей, а также большинство методов, которые есть у типа bytes, см. Методы Bytes и массива байтов.


Необязательный параметр source можно использовать для инициализации массива несколькими различными способами:


Если это строка, вы также должны указать параметры кодирования (и, необязательно, ошибки); затем bytearray() преобразует строку в байты с помощью str.encode() .


Если это целое число, массив будет иметь такой размер и будет инициализирован нулевыми байтами.


Если это объект, соответствующий интерфейсу buffer , буфер объекта, доступный только для чтения, будет использоваться для инициализации массива bytes.


Если это итерируемое значение, оно должно быть итерируемым из целых чисел в диапазоне 0 <= x < 256, которые используются в качестве начального содержимого массива.


Без аргумента создается массив размером 0.


Таким образом, bytes можно сделать гораздо больше, чем просто закодировать строку. Суть Pythonic в том, что он позволяет вызывать конструктор с любым типом исходного параметра, который имеет смысл.

Что касается кодирования строки, я думаю, что some_string.encode(encoding) это более питонистский подход, чем использование конструктора, потому что он наиболее самодокументируемый - "возьмите эту строку и закодируйте ее с помощью этой кодировки" понятнее, чем bytes(some_string, encoding) - при использовании конструктора нет явного глагола.

Я проверил исходный код Python. Если вы передаете строку unicode в bytes используя CPython , он вызывает PyUnicode_AsEncodedString, которая является реализацией encode; таким образом, вы просто пропускаете уровень косвенности, если вызываете encode самостоятельно.

Кроме того, смотрите Комментарий Сердалиса - unicode_string.encode(encoding) также более питонический, потому что он обратный byte_string.decode(encoding) и симметрия приятная.

Ответ 2

Это проще, чем кажется:

my_str = "hello world"
my_str_as_bytes = str.encode(my_str)
print(type(my_str_as_bytes)) # ensure it is byte representation
my_decoded_str = my_str_as_bytes.decode()
print(type(my_decoded_str)) # ensure it is string representation

вы можете проверить, напечатав типы. Обратитесь к выводам ниже.

<class 'bytes'>
<class 'str'>
Ответ 3

Абсолютно лучшим способом является не второй, а третий. Начиная с Python 3.0, первый параметр для encode по умолчанию имеет значение 'utf-8'. Таким образом, лучшим способом является

b = mystring.encode()

Это также будет быстрее, потому что аргумент по умолчанию приводит не к строке "utf-8" в коде C, а NULL, что намного быстрее проверить!

Вот несколько таймингов:

In [1]: %timeit -r 10 'abc'.encode('utf-8')
The slowest run took 38.07 times longer than the fastest.
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 183 ns per loop

In [2]: %timeit -r 10 'abc'.encode()
The slowest run took 27.34 times longer than the fastest.
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 137 ns per loop

Несмотря на предупреждение, время было очень стабильным после повторных запусков - отклонение составило всего ~ 2 процента.


Использование encode() без аргумента несовместимо с Python 2, поскольку в Python 2 кодировка символов по умолчанию - ASCII.

>>> 'äöä'.encode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
Ответ 4

Ответ на несколько иную проблему:

У вас есть последовательность необработанного unicode, которая была сохранена в переменной str:

s_str: str = "\x00\x01\x00\xc0\x01\x00\x00\x00\x04"

Вам нужно иметь возможность получить байтовый литерал этого юникода (для struct.unpack() и т.д.)

s_bytes: bytes = b'\x00\x01\x00\xc0\x01\x00\x00\x00\x04'

Решение:

s_new: bytes = bytes(s, encoding="raw_unicode_escape")

Ссылка (прокрутите вверх, чтобы найти стандартные кодировки):

Кодировки, специфичные для Python

python string python-3.x