2012-04-08 19 views
27

Podría explicar en detalle cuál es la diferencia entre la cadena de bytes y la cadena Unicode en Python. He leído this:cadena de bytes frente a cadena unicode. Python

código byte es simplemente el código fuente convertida en matrices de bytes

¿Quiere decir que Python tiene su propio formato de codificación/codificación? ¿O usa la configuración del sistema operativo? No entiendo. ¿Podría explicar por favor? ¡Gracias!

+8

coolinterview.com parece una terrible fuente de información. Yo no confiaría en eso. – bames53

+6

El "código de bytes" generalmente se refiere a algo completamente diferente, http://docs.python.org/glossary.html "El código fuente de Python se compila en bytecode, la representación interna de un programa de Python en el intérprete de CPython. almacenado en caché en archivos .py y .pyo " – dbr

+0

+1 Comentario de dbr. Bytecode es un detalle interno de implementación de CPython que no está relacionado con Unicode y probablemente no tenga que preocuparse. – bobince

Respuesta

28

No python no utiliza su propia codificación. Utilizará cualquier codificación a la que tenga acceso y que especifique. Un caracter en str representa un caracter Unicode. Sin embargo, para representar más de 256 caracteres, las codificaciones Unicode individuales utilizan más de un byte por carácter para representar muchos caracteres. Los objetos bytearray le dan acceso a los bytes subyacentes. Los objetos str tienen el método encode que toma una cadena que representa una codificación y devuelve el objeto bytearray que representa la cadena en esa codificación. Los objetos bytearray tienen el método decode que toma una cadena que representa una codificación y devuelve el str que resulta de interpretar el bytearray como una cadena codificada en la codificación especificada. Aquí hay un ejemplo.

>>> a = "αά".encode('utf-8') 
>>> a 
b'\xce\xb1\xce\xac' 
>>> a.decode('utf-8') 
'αά' 

Podemos ver que UTF-8 está usando cuatro bytes, \ XCE, \ xB1, \ XCE, y \ XAC para representar dos personajes. Después del artículo de Spolsky al que se refería Ignacio Vázquez-Abrams, leería el Python Unicode Howto.

+16

Probablemente debería mencionar que este código es para Python 3. – ovgolovin

+2

Quiere decir objetos 'bytes', no' bytearray': de hecho, 'tipo (" é ".encode ('UTF-8'))' es 'bytes' , no 'bytearray'. – EOL

+0

¿Qué versión de Python? 2.7 informa como ''. –

19

Aquí hay un intento de explicación simple que solo se aplica a Python 3. Espero que viniendo de una persona laica, ayude a aclarar algo de confusión para los completamente no iniciados. Si hay imprecisiones técnicas, pls me perdona y no dude en señalarlo.

supongamos que crea una cadena usando Python 3 en la forma habitual:

stringobject = 'ant' 

stringobject habría una cadena Unicode.

Una cadena Unicode se compone de caracteres Unicode. En stringobject arriba, los caracteres Unicode son las letras individuales, p. a, n, t

A cada carácter Unicode se le asigna un punto de código, que se puede expresar como una secuencia de dígitos hexadecimales (un dígito hexadecimal puede tomar 16 valores, que van de 0-9 y A-F). Por ejemplo, la letra 'a' es equivalente a '\u0091', y 'hormiga' es equivalente a '\u0061\u006E\u0074'.

Así se encuentra que si escribe,

stringobject = '\u0061\u006E\u0074' 
stringobject 

También obtendrá la salida 'ant'.

Ahora, Unicode se convierte en bytes, en un proceso conocido como codificación. El proceso inverso de convertir bytes a unicode se conoce como decodificación.

¿Cómo se hace esto? Como cada dígito hexadecimal puede tomar 16 valores diferentes, se puede reflejar en una secuencia binaria de 4 bits (por ejemplo, el dígito hexadecimal 0 puede expresarse en binario como 0000, el dígito hexadecimal 1 puede expresarse como 0001, etc.). Si un carácter Unicode tiene un punto de código que consta de cuatro dígitos hexadecimales, necesitaría una secuencia binaria de 16 bits para codificarlo.

Los diferentes sistemas de codificación especifican reglas diferentes para convertir unicode en bits. Lo que es más importante, las codificaciones difieren en la cantidad de bits que utilizan para expresar cada carácter Unicode.

Por ejemplo, el sistema de codificación ASCII utiliza solo 8 bits (1 byte) por carácter. Por lo tanto, solo puede codificar caracteres Unicode con puntos de código de hasta dos dígitos hexadecimales (es decir, 256 caracteres Unicode diferentes). El sistema de codificación UTF-8 utiliza 8 a 32 bits (1 a 4 bytes) por carácter, por lo que puede codificar caracteres Unicode con puntos de código de hasta 8 dígitos hexadecimales de largo, es decir, todo.

Ejecutar el siguiente código:

byteobject = stringobject.encode('utf-8') 
byteobject, type(byteobject) 

convierte una cadena Unicode en una cadena de bytes mediante el sistema de codificación UTF-8, y devuelve b'ant', bytes'.

Tenga en cuenta que si utilizó 'ASCII' como sistema de codificación, no tendría ningún problema ya que todos los puntos de código en 'ant' se pueden expresar con 1 byte. Pero si tuviera una cadena Unicode que contenga caracteres con puntos de código de más de dos dígitos hexadecimales, obtendrá un UnicodeEncodeError.

Del mismo modo,

stringobject = byteobject.decode('utf-8') 
stringobject, type(stringobject) 

le da 'ant', str.

+0

(1) En general, un carácter percibido por el usuario como 'g̈' puede corresponder a varios puntos de código Unicode (U + 0067 U + 0308 en este caso). (2) la codificación de un punto de código Unicode puede no estar relacionada con su número, es decir, la codificación de 8 bits puede representar ~ 0x100 caracteres, no es necesario que todos estos caracteres sean * consecutivos * (no es necesario que * "un código punto que consta de cuatro dígitos hexadecimales, necesitaría una secuencia binaria de 16 bits para codificarlo "* - no tiene sentido hablar del tamaño requerido para codificar un único punto de código - solo un conjunto de caracteres impone restricciones) – jfs

+0

Gracias. La mejor explicación que he leído. – parsecer