¿Cuál es la diferencia entre una cadena y una cadena de bytes?

Estoy trabajando con una biblioteca que devuelve una cadena de bytes y necesito convertirla en una cadena.

Aunque no estoy seguro de cuál es la diferencia, si la hay.

Suponiendo Python 3 (en Python 2, esta diferencia es un poco menos definida): una cadena es una secuencia de caracteres, es decir, puntos de código Unicode ; Estos son un concepto abstracto y no se pueden almacenar directamente en el disco. Una cadena de bytes es una secuencia de, por supuesto, bytes, cosas que pueden almacenarse en el disco. La asignación entre ellos es una encoding : hay muchos de estos (y son infinitos muchos posibles), y usted necesita saber qué se aplica en el caso particular para realizar la conversión, ya que una encoding diferente puede asignar los mismos bytes. a una cadena diferente:

>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-16') '蓏콯캁澽苏' >>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-8') 'τoρνoς' 

Una vez que sepa cuál usar, puede usar el método .decode() de la cadena de bytes para obtener la cadena de caracteres correcta de la anterior. Para completar, el método .encode() de una cadena de caracteres va en sentido opuesto:

 >>> 'τoρνoς'.encode('utf-8') b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82' 

Lo único que una computadora puede almacenar es bytes.

Para almacenar cualquier cosa en una computadora, primero debe codificarlo , es decir, convertirlo a bytes. Por ejemplo:

  • Si desea almacenar música, primero debe codificarla utilizando MP3 , WAV , etc.
  • Si desea almacenar una imagen, primero debe codificarla utilizando PNG , JPEG , etc.
  • Si desea almacenar texto, primero debe codificarlo utilizando ASCII , UTF-8 , etc.

MP3 , WAV , PNG , JPEG , ASCII y UTF-8 son ejemplos de codificaciones . Una encoding es un formato para representar audio, imágenes, texto, etc. en bytes.

En Python, una cadena de bytes es solo eso: una secuencia de bytes. No es legible por humanos. Debajo del capó, todo debe convertirse en una cadena de bytes antes de que pueda almacenarse en una computadora.

Por otro lado, una cadena de caracteres, a menudo llamada “cadena”, es una secuencia de caracteres. Es legible por humanos. Una cadena de caracteres no se puede almacenar directamente en una computadora, debe codificarse primero (convertirse en una cadena de bytes). Existen múltiples codificaciones a través de las cuales una cadena de caracteres se puede convertir en una cadena de bytes, como ASCII y UTF-8 .

 'I am a string'.encode('ASCII') 

El código de Python anterior codificará la cadena 'I am a string' utilizando la encoding ASCII . El resultado del código anterior será una cadena de bytes. Si lo imprimes, Python lo representará como b'I am a string' . Sin embargo, recuerde que las cadenas de bytes no son legibles por humanos , solo Python las decodifica desde ASCII cuando las imprime. En Python, una cadena de bytes se representa con una b , seguida de la representación ASCII la cadena de bytes.

Una cadena de bytes se puede decodificar de nuevo en una cadena de caracteres, si conoce la encoding que se utilizó para codificarla.

 b'I am a string'.decode('ASCII') 

El código anterior devolverá la cadena original 'I am a string' .

La encoding y deencoding son operaciones inversas. Todo debe estar codificado antes de que pueda escribirse en el disco, y debe decodificarse antes de que un humano pueda leerlo.

En Python 2 , str consta de secuencias de valores de 8 bits, mientras que unicode consta de secuencias de caracteres Unicode. Una cosa a tener en cuenta es que str y unicode se pueden usar junto con los operadores si str solo consta de caracteres ASCI de 7 bits.

En Python 3 , los bytes consisten en secuencias de valores de 8 bits, mientras que str consiste en secuencias de caracteres Unicode. bytes y str no se pueden usar junto con operadores como > o + .

Podría ser útil usar las funciones de ayuda para convertir entre str y unicode en Python 2, y entre bytes y str en Python 3.

De lo que es Unicode :

Fundamentalmente, las computadoras solo se ocupan de los números. Almacenan letras y otros caracteres asignando un número para cada uno.

……

Unicode proporciona un número único para cada personaje, sin importar la plataforma, sin importar el progtwig, sin importar el idioma.

Entonces, cuando una computadora representa una cadena, encuentra caracteres almacenados en la computadora de la cadena a través de su número Unicode único y estas cifras se almacenan en la memoria. Pero no puede escribir directamente la cadena en el disco o transmitir la cadena en la red a través de su número Unicode único porque estas cifras son solo un número decimal simple. Debe codificar la cadena a la cadena de bytes, como UTF-8 . UTF-8 es una encoding de caracteres capaz de codificar todos los caracteres posibles y almacena los caracteres como bytes (se parece a esto ). Por lo tanto, la cadena codificada se puede usar en todas partes porque UTF-8 casi es compatible en todas partes Cuando abre un archivo de texto codificado en UTF-8 desde otros sistemas, su computadora lo decodificará y mostrará los caracteres a través de su número Unicode único. Cuando un navegador recibe datos de cadena codificados en UTF-8 de la red, decodificará los datos a cadena (suponga que el navegador está en UTF-8 ) y mostrará la cadena.

En python3, puedes transformar la cadena y la cadena de bytes entre sí:

 >>> print('中文'.encode('utf-8')) b'\xe4\xb8\xad\xe6\x96\x87' >>> print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))中文 

En una palabra, la cadena es para mostrar a los seres humanos para leer en una computadora y la cadena de bytes es para almacenar en el disco y la transmisión de datos.