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

существует два разных способа преобразования строки в байты, как видно из ответов на TypeError:' str ' не поддерживает интерфейс буфера

какой из этих методов будет лучше или более подходящие для Python? Или это просто вопрос личных предпочтений?

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

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

5 ответов


если вы посмотрите на документы для bytes, Он указывает вам!--11-->bytearray:

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

возвращает новый массив байтов. Тип bytearray представляет собой изменяемую последовательность целых чисел в диапазоне 0

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

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

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

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

если это метод, то он должен быть итерируемым целых чисел в диапазоне 0

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

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

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

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

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


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

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

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

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)

вы можете просто преобразовать строку в байты, используя:

a_string.encode()

и вы можете просто преобразовать байты в строку, используя:

some_bytes.decode()

bytes.decode и str.encode есть encoding='utf-8' как значение по умолчанию.

следующие функции (взято из Эффективный Python) может быть полезно конвертировать str to bytes и bytes to str:

def to_bytes(bytes_or_str):
    if isinstance(bytes_or_str, str):
        value = bytes_or_str.encode() # uses 'utf-8' for encoding
    else:
        value = bytes_or_str
    return value # Instance of bytes


def to_str(bytes_or_str):
    if isinstance(bytes_or_str, bytes):
        value = bytes_or_str.decode() # uses 'utf-8' for encoding
    else:
        value = bytes_or_str
    return value # Instance of str

so_string = 'stackoverflow'
so_bytes = so_string.encode( )