2009-01-15 95 views
152

Nunca he estado seguro de entender la diferencia entre decodificar str/unicode y codificar.¿Cuál es la diferencia entre codificar/decodificar?

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

Sé que unicode().encode() convierte los 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(). ¿Alguien puede explicar, y posiblemente también corregir, todo lo demás que me he equivocado anteriormente?

EDIT:

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

+0

Creo que la segunda respuesta de [esta página] (http://stackoverflow.com/questions/10288016/usage-of-unicode-and-encode-functions-in-python) es lo suficientemente clara y concisa. – Ben

Respuesta

92

El método decode de cadenas Unicode realmente no tiene ninguna aplicación en absoluto (a menos que tengas algunas ext datos en una cadena Unicode por alguna razón - ver a continuación). Es principalmente allí por razones históricas, creo. En Python 3, se ha ido por completo.

unicode().decode() realizará una implícita codificación de s usando el códec predeterminado (ascii). Verifique 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.

Para str().encode() que es al revés - que intenta una implícita decodificación 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) 

Se utiliza como este, str().encode() también es superfluo.

Pero hay otra aplicación de este último método que es útil: hay encodings que no tienen nada que ver con los juegos de caracteres, y por lo tanto se puede aplicar a las 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 "codificación" para estas dos aplicaciones es ... awkard. Nuevamente, con tipos de byte y string separados en Python 3, esto ya no es un problema.

+2

'.decode()' en cadenas Unicode podría ser útil, por ejemplo, 'print u '\\ u0203'.decode (' unicode-escape ')' – jfs

+0

+1 para la mención de codificaciones sin caracteres (es decir, zip). – dotancohen

+0

Buen ejemplo @JFSebastian en python3 Supongo que harías: 'print u '\\ u0203'.encode (' utf8 '). Decode (' unicode-escape ')' – AJP

5

Existen algunas codificaciones que se pueden utilizar para des/codificar de str a str o de unicode a unicode. Por ejemplo base64, hex o incluso rot13. Se enumeran en el codecs module.

Editar:

La decodificación de los mensajes en una cadena Unicode puede deshacer la correspondiente operación de codificación:

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

El tipo devuelto se str en lugar de Unicode lo cual es lamentable, en mi opinión. Pero cuando no se está haciendo una descodificación adecuada entre str y unicode, de todos modos parece un desastre.

+1

-1: El método de decodificación no se está aplicando al objeto Unicode. En cambio, el objeto Unicode se codifica como una cadena de bytes 'ascii' antes de que comience la operación de decodificación. Para una prueba de esa afirmación, pruebe u'ã'.decode ('hex') - que arroja UnicodeEncodeError – nosklo

+2

@nosklo: Tiene razón. Lo que realmente quise decir es que los objetos Unicode tienen un método decode() para que pueda aplicar códigos que no sean de codificación de caracteres también. Todo este negocio que no codifica los caracteres hace que esta interfaz sea un desastre en Python <3. –

12

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

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

No estoy seguro de para qué decodificar un texto decodificado ya es bueno. Al intentarlo con cualquier codificación, parece que siempre intenta codificar primero con la codificación predeterminada del sistema.

+0

¡Esto es maravilloso! Gracias. – dotancohen

58

Para representar una cadena Unicode como una cadena de bytes se conoce como que codifica. Use 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) 

Por lo general, codificar una cadena Unicode siempre que necesite utilizarlo para IO, por ejemplo, transferir por la red, o guardarlo en un archivo de disco.

Para convertir una cadena de bytes en una cadena unicode se conoce como descodificando. Use unicode('...', encoding) o '...'.decodificar (codificar).

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' 

Por lo general, decodificar una cadena de bytes cada vez que recibe datos de la cadena desde la red o desde un archivo de disco.

Creo que hay algunos cambios en el manejo de Unicode en Python 3, por lo que el anterior, probablemente no es la correcta para el pitón 3.

Algunos buenos enlaces:

+6

No respondió la pregunta del OP. OP quiere saber qué hacen str.encode() y unicode.decode(). Usted acaba de repetir lo que se dijo en la pregunta original. – stuckintheshuck

+0

Gran respuesta para explicar por qué en la práctica alguna vez te has equivocado con la decodificación y la codificación. No todas las máquinas entienden el mismo conjunto de caracteres, pero todos entienden los bytes.Codifique en bytes para que las computadoras de un idioma comprendan universalmente (y puedan ser transferidas o guardadas en un disco), pero decodifique cuando los humanos realmente tengan que leer esos bytes (por ejemplo, en el lado del cliente). –

11

anUnicode. codificar ('encoding') se traduce en una objeto cadena y se puede llamar en un objeto Unicode

unaCadena. decodificar ('codificación') da como resultado un objeto unicode y se puede invocar en una cadena, codificada en la codificación dada.


Algunos más explicaciones:

Se puede crear un objeto Unicode, que no tiene ningún conjunto de codificación. La forma en que está almacenada por Python 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 el que desea imprimir su objeto Unicode en la consola o en algún archivo de texto. Entonces tiene que codificar (por ejemplo, en UTF-8), llamar a codificar ('utf-8') y se obtiene una cadena con '\ u < algúnNúmero >' dentro, que es perfectamente imprimible.

Entonces, una vez más - que le gustaría hacer lo contrario - cadena leer codificado en UTF-8 y tratarlo como un Unicode, por lo que el \ U360 sería un personaje, no 5. A continuación, decodificar una cadena (con la codificación seleccionada) y obtén un nuevo objeto del tipo Unicode.

Como nota al margen: puede seleccionar una 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 implica UTF-8/UTF-16 y cadena.

0

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

Usemos un ejemplo para ilustrar:

el equipo utiliza la unidad básica de bytes para almacenar y procesar la 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) caracteres chinos cuando se les da un diccionario para buscar esa palabra china, en este caso, es diccionario "utf-8", y no mostraría correctamente la palabra china deseada si busca en un diccionario diferente o incorrecto (usando un método de decodificación diferente).

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

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

por lo que la información de codificación son los bytes sin procesar, y la información decodificada son los bytes sin formato y el nombre del diccionario de referencia (pero no el diccionario en sí).

Cuestiones relacionadas