Лучший способ преобразовать строку в байты в Python 3? - PullRequest
640 голосов
/ 28 сентября 2011

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

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

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

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

Ответы [ 5 ]

471 голосов
/ 28 сентября 2011

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

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

Возвращает новый массив байтов.Тип bytearray - это изменяемая последовательность целых чисел в диапазоне 0 <= x <256. Он имеет большинство обычных методов изменяемых последовательностей, описанных в Mutable Sequence Types, а также большинство методов, которые имеет тип bytes, см. Байты иМетоды байтового массива. </p>

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

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

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

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

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

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

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

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

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

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

233 голосов
/ 06 июля 2013

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

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
88 голосов
/ 23 июля 2017

абсолютно лучший способ - не 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)
39 голосов
/ 04 сентября 2017

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

a_string.encode()

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

some_bytes.decode()

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

Следующие функции (взятые из Effective Python ) могут быть полезны для преобразования str в bytesи bytes до 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
9 голосов
/ 05 апреля 2017
so_string = 'stackoverflow'
so_bytes = so_string.encode( )
...