Если вы посмотрите документы для 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: