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


Nunca he estado seguro de entender la diferencia entre str/unicode decodificar y codificar.

Sé que str().decode() es para cuando tienes una cadena de bytes que sabes que tiene cierta codificación de caracteres, dado ese nombre de codificación devolverá una cadena unicode.

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

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

EDITAR:

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

Author: cedbeu, 2009-01-15

7 answers

El método decode de cadenas unicode realmente no tiene ninguna aplicación en absoluto (a menos que tenga algunos datos no textuales en una cadena unicode por alguna razón see ver más abajo). Creo que está ahí principalmente por razones históricas. En Python 3 se ha ido por completo.

unicode().decode() realizará una codificación implícita de s usando el códec predeterminado (ascii). Verifica esto de la siguiente manera:

>>> s = u'ö'
>>> s.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
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 "<stdin>", line 1, in <module>
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.

Porque str().encode() es al revés alrededor de attempts intenta una decodificación implícita de s con la codificación predeterminada:

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

Usado así, 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 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'

Tiene razón, sin embargo: el uso ambiguo de "codificación" para ambas aplicaciones es... awkard. De nuevo, con los tipos byte y string separados en Python 3, esto ya no es un problema.

 96
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-07 17:53:24

Representar una cadena unicode como una cadena de bytes se conoce como encoding. Utilizar 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: 'ascii' codec can't encode characters in position 0-5: 
    ordinal not in range(128)

Normalmente 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 a una cadena unicode se conoce como decodificación. Utilizar unicode('...', encoding) o"...'.decode(codificación).

Ejemplo:

   >>> u'æøå'
   u'\xc3\xa6\xc3\xb8\xc3\xa5' # the interpreter prints the unicode object like so
   >>> 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 es correcto para python 3.

Algunos buenos enlaces:

 62
Author: codeape,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-23 07:39:52

AnUnicode. encode ('encoding') resulta en un objeto string y se puede invocar en un objeto unicode

aString. decode ('encoding') resulta en un objeto unicode y se puede llamar en una cadena, codificada en una codificación dada.

Algunas explicaciones más:

Puede crear algún objeto unicode, que no tiene ningún conjunto de codificación. La forma en que Python lo almacena en la memoria no es de tu incumbencia. Puedes buscarlo, dividirlo y llamar cualquier función de manipulación de cadenas que te guste.

Pero llega un momento en el que desea imprimir su objeto unicode en 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' dentro, que es perfectamente imprimible.

Entonces, de nuevo - le gustaría hacer lo contrario - leer cadena codificada en UTF-8 y tratarla como un Unicode, por lo que el \u360 sería un carácter, no 5. Entonces tú decodifica una cadena (con la codificación seleccionada) y obtiene un nuevo objeto del tipo unicode.

Como nota al margen - puede seleccionar alguna codificación pervertida, como 'zip', 'base64', 'rot' y algunos de ellos convertirán de cadena a cadena, pero creo que el caso más común es uno que involucra UTF-8/UTF-16 y cadena.

 13
Author: Abgan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-16 23:11:40

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

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

No estoy seguro de para qué sirve decodificar un texto unicode ya decodificado. Intentar eso con cualquier codificación parece siempre intentar codificar primero con la codificación predeterminada del sistema.

 12
Author: nosklo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-15 16:15:39

Deberías leer Python UnicodeDecodeError - Soy un malentendido codificar. Mi comprensión de unicode en Python fue mucho más clara después de leer la respuesta aceptada.

 8
Author: Oli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:06

Hay algunas codificaciones que se pueden usar para de-/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 decodificación en una cadena unicode puede deshacer la operación de codificación 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á haciendo una decodificación en-/adecuada entre str y unicode, esto parece un desastre Por cierto.

 5
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-15 19:13:01

La respuesta simple es que son exactamente lo opuesto el uno del otro.

La computadora utiliza la unidad muy 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 (lo que significa imprimir o almacenar) que son caracteres chinos cuando se les da un diccionario para buscar esa palabra china, en este caso, es el diccionario "utf-8", y no puede mostrar correctamente la palabra china deseada si busca en un diccionario diferente o incorrecto (utilizando un método de decodificación diferente).

En el caso anterior, el proceso para que una computadora busque la palabra china es decoding().

Y el proceso de la computadora escribiendo el chino en la memoria de la computadora es encode ().

Así que la información de codificación son los bytes crudos, y la información decodificada son los bytes crudos y el nombre del diccionario a referenciar (pero no el diccionario sí mismo).

 0
Author: Eren Bay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-03 18:32:06