¿Cuál es la mejor manera de convertir una cadena en bytes en Python 3?

Parece que hay dos formas diferentes de convertir una cadena en bytes, como se ve en las respuestas a https://stackoverflow.com/questions/5471158/typeerror-str-does-not-support-the-buffer-interface

¿Cuál de estos métodos sería mejor o más pitónico? ¿O es sólo una cuestión de preferencia personal?

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

b = mystring.encode('utf-8')
Solución

Si miras la documentación de bytes, te indica bytearray:

bytearray([fuente[, codificación[, errores]])

Devuelve un nuevo array de bytes. El tipo bytearray es una secuencia mutable de enteros en el rango 0 <= x < 256. Tiene la mayoría de los métodos habituales de las secuencias mutables, descritos en Tipos de Secuencias Mutables, así como la mayoría de los métodos que tiene el tipo bytes, ver Métodos de Bytes y Matrices de Bytes.

El parámetro opcional source puede ser usado para inicializar el array de varias maneras:

Si es una cadena, también debe dar los parámetros de codificación (y opcionalmente, errores); bytearray() entonces convierte la cadena a bytes usando str.encode().

Si es un entero, el array tendrá ese tamaño y se inicializará con bytes nulos.__

Si se trata de un objeto que se ajusta a la interfaz del buffer, se utilizará un buffer de sólo lectura del objeto para inicializar el array de bytes.__

Si es un iterable, debe ser un iterable de enteros en el rango 0

Comentarios (5)

Es más fácil de lo que se cree:

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
Comentarios (10)

La forma absolutamente mejor no es ninguna de las dos, sino la tercera. El primer parámetro de encode por defecto 'utf-8' desde Python 3.0. Por lo tanto, la mejor manera es

b = mystring.encode()

Esto también será más rápido, porque el argumento por defecto no resulta en la cadena "utf-8"en el código C, sino *NULL`, ¡que es mucho* más rápido de comprobar!

Aquí hay algunos tiempos:

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

A pesar de la advertencia, los tiempos fueron muy estables después de repetidas ejecuciones - la desviación fue de sólo ~ 2 por ciento.


Usar encode() sin un argumento no es compatible con Python 2, ya que en Python 2 la codificación de caracteres por defecto es ASCII.

>>> 'äöä'.encode()
Traceback (most recent call last):
  File "", line 1, in 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
Comentarios (2)