¿Cuál es la diferencia entre codificar / decodificar?

Nunca he estado seguro de entender la diferencia entre deencoding y encoding de Str / Unicode.

Sé que str().decode() es para cuando tiene una cadena de bytes que sabe que tiene una cierta encoding de caracteres, dado que el nombre de la encoding devolverá una cadena Unicode.

Sé que unicode().encode() convierte caracteres Unicode en una cadena de bytes de acuerdo con un nombre de encoding dado.

Pero no entiendo para qué son str().encode() y unicode().decode() . ¿Alguien puede explicar, y posiblemente también corregir algo más que me haya equivocado anteriormente?

EDITAR:

Varias respuestas dan información sobre lo que hace .encode en una cadena, pero nadie parece saber qué hace .decode para Unicode.

El método de decode de las cadenas de Unicode realmente no tiene ninguna aplicación (a menos que tenga algunos datos que no sean de texto en una cadena de Unicode por alguna razón, consulte a continuación). Creo que está principalmente allí por razones históricas. En Python 3 se ha ido completamente.

unicode().decode() realizará una encoding implícita de s utilizando el códec predeterminado (ascii). Verifique esto de esta manera:

 >>> s = u'ö' >>> s.decode() Traceback (most recent call last): File "", line 1, in  UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0: ordinal not in range(128) >>> s.encode('ascii') Traceback (most recent call last): File "", line 1, in  UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0: ordinal not in range(128) 

Los mensajes de error son exactamente los mismos.

Para str().encode() es al revés: intenta una deencoding implícita de s con la encoding predeterminada:

 >>> s = 'ö' >>> s.decode('utf-8') u'\xf6' >>> s.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) 

Utilizado de esta manera, str().encode() también es superfluo.

Pero hay otra aplicación del último método que es útil: hay codificaciones que no tienen nada que ver con los conjuntos de caracteres, y por lo tanto se pueden aplicar a cadenas de 8 bits de una manera significativa:

 >>> s.encode('zip') 'x\x9c;\xbc\r\x00\x02>\x01z' 

Sin embargo, tiene razón: el uso ambiguo de la “encoding” para ambas aplicaciones es … incómodo. De nuevo, con string tipos de byte y string separados en Python 3, esto ya no es un problema.

Representar una cadena Unicode como una cadena de bytes se conoce como encoding . Utilice u'...'.encode(encoding) .

Ejemplo:

     >>> u'æøå'.encode ('utf8')
     '\ xc3 \ x83 \ xc2 \ xa6 \ xc3 \ x83 \ xc2 \ xb8 \ xc3 \ x83 \ xc2 \ xa5'
     >>> u'æøå'.encode ('latin1')
     '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'
     >>> u'æøå'.encode ('ascii')
     UnicodeEncodeError: el codec 'ascii' no puede codificar caracteres en la posición 0-5: 
     ordinal no está dentro del rango (128)

Por lo general, codifica una cadena Unicode cada vez que necesita usarla para IO, por ejemplo, transferirla a través de la red o guardarla en un archivo de disco.

Para convertir una cadena de bytes en una cadena Unicode se conoce como deencoding . Utilice unicode('...', encoding) o ‘…’. Deencoding (encoding).

Ejemplo:

    >>> u'æøå '
    u '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5' # el intérprete imprime el objeto Unicode como tal
    >>> unicode ('\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5', 'latin1')
    u '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'
    >>> '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'.decode (' latin1 ')
    u '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'

Normalmente, decodifica una cadena de bytes cada vez que recibe datos de cadena de la red o de un archivo de disco.

Creo que hay algunos cambios en el manejo de Unicode en Python 3, por lo que lo anterior probablemente no sea correcto para Python 3.

Algunos buenos enlaces:

  • El Absoluto Mínimo Todo desarrollador de software Absolutamente, positivamente debe saber acerca de Unicode y los conjuntos de caracteres (¡sin excusas!)
  • Unicode HOWTO

unnnicode. encode (‘encoding’) da como resultado un objeto de cadena y se puede llamar en un objeto Unicode

una cuerda. La deencoding (‘encoding’) da como resultado un objeto Unicode y se puede llamar en una cadena, codificada en una encoding dada.


Algunas explicaciones más:

Puede crear algún objeto Unicode, que no tiene ningún conjunto de encoding. La forma en que Python lo almacena en la memoria no es de su incumbencia. Puede buscarlo, dividirlo y llamar a cualquier función de manipulación de cadenas que desee.

Pero llega un momento en que le gustaría imprimir su objeto Unicode para la consola o en algún archivo de texto. Así que tienes que codificarlo (por ejemplo, en UTF-8), llamas a encode (‘utf-8’) y obtienes una cadena con ‘\ u ‘ adentro, que es perfectamente imprimible.

Luego, de nuevo, le gustaría hacer lo contrario: leer la cadena codificada en UTF-8 y tratarla como Unicode, por lo que \ u360 sería un carácter, no 5. Luego, decodificará una cadena (con la encoding seleccionada) y Obtener nuevo objeto de tipo Unicode.

Solo como nota al margen: puede seleccionar alguna encoding pervertida, como ‘zip’, ‘base64’, ‘rot’ y algunas de ellas se convertirán de una cadena a otra, pero creo que el caso más común es el que involucra UTF-8. / UTF-16 y cadena.

mybytestring.encode (somecodec) es significativo para estos valores de somecodec :

  • base64
  • bz2
  • zlib
  • maleficio
  • quopri
  • rot13
  • string_escape
  • uu

No estoy seguro de para qué sirve decodificar un texto Unicode ya descodificado. Intentar eso con cualquier encoding parece intentar siempre codificar primero con la encoding predeterminada del sistema.

Debería leer Python UnicodeDecodeError – ¿Estoy malentendido en la encoding ? Mi comprensión de Unicode en Python fue mucho más clara después de leer la respuesta aceptada.

Hay algunas codificaciones que se pueden usar para decodificar / codificar de str a str o de unicode a unicode. Por ejemplo base64, hex o incluso rot13. Se enumeran en el módulo de codecs .

Editar:

El mensaje de deencoding en una cadena Unicode puede deshacer la operación de encoding correspondiente:

 In [1]: u'0a'.decode('hex') Out[1]: '\n' 

El tipo devuelto es str en lugar de unicode, lo cual es desafortunado en mi opinión. Pero cuando no estás haciendo un en / deencoding adecuado entre str y unicode, esto parece un desastre de todos modos.

La respuesta simple es que son exactamente lo opuesto entre sí.

la computadora utiliza la unidad básica de byte para almacenar y procesar información, no tiene sentido para los ojos humanos.

por ejemplo, ‘\ xe4 \ xb8 \ xad \ xe6 \ x96 \ x87’ es la representación de dos caracteres chinos, pero la computadora solo sabe (es decir, imprimir o almacenar) son caracteres chinos cuando se les da un diccionario para buscar eso La palabra china, en este caso, es el diccionario “utf-8”, y no mostrará correctamente la palabra china deseada si observa un diccionario diferente o incorrecto (utilizando un método de deencoding diferente).

En el caso anterior, el proceso para que una computadora busque una palabra china está decodificando ().

Y el proceso de escritura de la computadora en chino en la memoria de la computadora es codificar ().

por lo que la información de encoding es los bytes en bruto, y la información descodificada son los bytes en bruto y el nombre del diccionario para referencia (pero no el diccionario en sí).