Parece que hay dos formas diferentes de convertir una cadena a bytes, como se ve en las respuestas a TypeError: 'str' no es compatible con la interfaz del búfer
¿Cuál de estos métodos sería mejor o más pitónico? ¿O es solo una cuestión de preferencia personal?
b = bytes(mystring, 'utf-8')
b = mystring.encode('utf-8')
python
string
character-encoding
python-3.x
Mark Ransom
fuente
fuente
bytes(item, "utf8")
, ya que lo explícito es mejor que lo implícito, así que ... porstr.encode( )
defecto es silencioso en bytes, lo que te hace más Unicode-zen pero menos Explicit-Zen. También "común" no es un término que me gusta seguir. Además,bytes(item, "utf8")
es más como elstr()
, y lasb"string"
anotaciones. Mis disculpas si soy tan novato para entender sus razones. Gracias.encode()
no llamabytes()
, es al revés. Por supuesto, eso no es inmediatamente obvio, por eso hice la pregunta.Respuestas:
Si miras los documentos
bytes
, te indicabytearray
:Por
bytes
lo tanto, puede hacer mucho más que solo codificar una cadena. Es Pythonic que le permitiría llamar al constructor con cualquier tipo de parámetro fuente que tenga sentido.Para codificar una cadena, creo que
some_string.encode(encoding)
es más Pythonic que usar el constructor, porque es el más autodocumentado: "tomar esta cadena y codificarla con esta codificación" es más claro quebytes(some_string, encoding)
: no hay un verbo explícito cuando se usa el constructor.Editar: Revisé la fuente de Python. Si pasa una cadena unicode a
bytes
CPython, llama a PyUnicode_AsEncodedString , que es la implementación deencode
; así que solo te estás saltando un nivel de indirección si te llamas aencode
ti mismo.Además, vea el comentario de Serdalis:
unicode_string.encode(encoding)
también es más pitónico porque es inversobyte_string.decode(encoding)
y la simetría es agradable.fuente
unicode_string.encode(encoding)
coincide muy bien conbytearray.decode(encoding)
cuando quieres recuperar tu cadena.bytearray
se usa cuando necesita un objeto mutable. No lo necesita para conversiones simplesstr
↔bytes
.bytearray
excepto que los documentosbytes
no dan detalles, solo dicen "esta es una versión inmutable debytearray
", así que tengo que citar a partir de ahí.bytes
: Evite usar el tipo de bytes como una función con un argumento entero. En v2, esto devuelve el entero convertido a una cadena (byte) porque bytes es un alias para str, mientras que en v3 devuelve una cadena de bytes que contiene el número dado de caracteres nulos. Entonces, por ejemplo, en lugar de los bytes de expresión v3 (6), use el equivalente b '\ x00' * 6, que funciona perfectamente de la misma manera en cada versión.byte_string.decode('latin-1')
comoutf-8
que no cubre todo el rango de 0x00 a 0xFF (0-255), consulte los documentos de Python para más información.Es más fácil de lo que se piensa:
fuente
obj.method()
sintaxis en lugar de lacls.method(obj)
sintaxis, es decir, usebytestring = unicode_text.encode(encoding)
yunicode_text = bytestring.decode(encoding)
.self
el primer argumentoencode
como método enlazado en la cadena. Esta respuesta sugiere que en su lugar debería llamar al método independiente y pasarle la cadena. Esa es la única información nueva en la respuesta, y está mal.La absolutamente mejor manera es que ninguno de los 2, pero el tercero. El primer parámetro predeterminado es desde Python 3.0. Por lo tanto, la mejor manera es
encode
'utf-8'
¡Esto también será más rápido, porque el argumento predeterminado no da como resultado la cadena
"utf-8"
en el código C, sinoNULL
que es mucho más rápido verificar!Aquí hay algunos horarios:
A pesar de la advertencia, los tiempos fueron muy estables después de repetidas ejecuciones: la desviación fue de solo ~ 2 por ciento.
Usar
encode()
sin argumento no es compatible con Python 2, ya que en Python 2 la codificación de caracteres predeterminada es ASCII .fuente
'\u00012345'*10000
. Ambos toman 28.8us en mi laptop; presumiblemente, los 50ns adicionales se pierden en el error de redondeo. Por supuesto, este es un ejemplo bastante extremo, pero'abc'
es igual de extremo en la dirección opuesta.