Unicode y las codificaciones son cosas completamente diferentes y no relacionadas.
Unicode
Asigna una identificación numérica a cada carácter:
- 0x41 → A
- 0xE1 → á
- 0x414 → Д
Entonces, Unicode asigna el número 0x41 a A, 0xE1 a á y 0x414 a Д.
Incluso la pequeña flecha → que utilicé tiene su número Unicode, es 0x2192. E incluso los emojis tienen sus números Unicode, 😂 es 0x1F602.
Puede buscar los números Unicode de todos los caracteres en esta tabla . En particular, puede encontrar los primeros tres caracteres arriba aquí , la flecha aquí y el emoji aquí .
Estos números asignados a todos los caracteres por Unicode se denominan puntos de código .
El propósito de todo esto es proporcionar un medio para hacer referencia inequívoca a cada carácter. Por ejemplo, si estoy hablando de 😂, en lugar de decir "ya sabes, este emoji riendo con lágrimas" , solo puedo decir, punto de código Unicode 0x1F602 . Más fácil, ¿verdad?
Tenga en cuenta que los puntos de código Unicode generalmente se formatean con un principio U+
, luego el valor numérico hexadecimal se completa con al menos 4 dígitos. Entonces, los ejemplos anteriores serían U + 0041, U + 00E1, U + 0414, U + 2192, U + 1F602.
Los puntos de código Unicode van desde U + 0000 a U + 10FFFF. Eso es 1,114,112 números. 2048 de estos números se utilizan para sustitutos , por lo que quedan 1,112,064. Esto significa que Unicode puede asignar un ID único (punto de código) a 1,112,064 caracteres distintos. Aún no todos estos puntos de código están asignados a un carácter y Unicode se extiende continuamente (por ejemplo, cuando se introducen nuevos emojis).
Lo importante a recordar es que todo lo que hace Unicode es asignar un ID numérico, llamado punto de código, a cada carácter para una referencia fácil y sin ambigüedades.
Codificaciones
Asignar caracteres a patrones de bits.
Estos patrones de bits se utilizan para representar los caracteres en la memoria de la computadora o en el disco.
Hay muchas codificaciones diferentes que cubren diferentes subconjuntos de caracteres. En el mundo de habla inglesa, las codificaciones más comunes son las siguientes:
Asigna 128 caracteres (puntos de código U + 0000 a U + 007F) a patrones de bits de longitud 7.
Ejemplo:
Puede ver todas las asignaciones en esta tabla .
Asigna 191 caracteres (puntos de código U + 0020 a U + 007E y U + 00A0 a U + 00FF) a patrones de bits de longitud 8.
Ejemplo:
- a → 01100001 (0x61)
- á → 11100001 (0xE1)
Puede ver todas las asignaciones en esta tabla .
Mapas 1,112,064 caracteres (todos los puntos de código Unicode existentes) a patrones de bits de cualquiera de longitud 8, 16, 24, o 32 bits (es decir, 1, 2, 3, o 4 bytes).
Ejemplo:
- a → 01100001 (0x61)
- á → 11000011 10100001 (0xC3 0xA1)
- ≠ → 11100010 10001001 10100000 (0xE2 0x89 0xA0)
- 😂 → 11110000 10011111 10011000 10000010 (0xF0 0x9F 0x98 0x82)
La forma en que UTF-8 codifica caracteres en cadenas de bits se describe muy bien aquí .
Unicode y codificaciones
Al observar los ejemplos anteriores, queda claro cómo es útil Unicode.
Por ejemplo, si soy Latin-1 y quiero explicar mi codificación de á, no necesito decir:
"Codifico que a con un aigu (o como se llame a esa barra ascendente) como 11100001"
Pero solo puedo decir:
"Codifico U + 00E1 como 11100001"
Y si soy UTF-8 , puedo decir:
"Yo, a mi vez, codifico U + 00E1 como 11000011 10100001"
Y es inequívocamente claro para todos a qué personaje nos referimos.
Ahora a la confusión que a menudo surge
Es cierto que a veces el patrón de bits de una codificación, si lo interpreta como un número binario, es el mismo que el punto de código Unicode de este carácter.
Por ejemplo:
- ASCII codifica a como 1100001, que puede interpretar como el número hexadecimal 0x61 , y el punto de código Unicode de a es U + 0061 .
- Latin-1 codifica á como 11100001, que puede interpretar como el número hexadecimal 0xE1 , y el punto de código Unicode de á es U + 00E1 .
Por supuesto, esto se ha organizado así a propósito para mayor comodidad. Pero deberías verlo como una pura coincidencia . El patrón de bits utilizado para representar un carácter en la memoria no está vinculado de ninguna manera al punto de código Unicode de este carácter.
Nadie incluso dice que tienes que interpretar una cadena de bits como 11100001 como un número binario. Míralo como la secuencia de bits que Latin-1 usa para codificar el carácter á .
De vuelta a tu pregunta
La codificación que usa su intérprete de Python es UTF-8 .
Esto es lo que sucede en sus ejemplos:
Ejemplo 1
Lo siguiente codifica el carácter á en UTF-8. Esto da como resultado la cadena de bits 11000011 10100001, que se guarda en la variable a
.
>>> a = 'á'
Cuando observa el valor de a
, su contenido 11000011 10100001 tiene el formato del número hexadecimal 0xC3 0xA1 y se genera como '\xc3\xa1'
:
>>> a
'\xc3\xa1'
Ejemplo 2
Lo siguiente guarda el punto de código Unicode de á, que es U + 00E1, en la variable ua
(no sabemos qué formato de datos usa Python internamente para representar el punto de código U + 00E1 en la memoria, y no es importante para nosotros):
>>> ua = u'á'
Cuando observa el valor de ua
, Python le dice que contiene el punto de código U + 00E1:
>>> ua
u'\xe1'
Ejemplo 3
Lo siguiente codifica el punto de código Unicode U + 00E1 (que representa el carácter á) con UTF-8, lo que da como resultado el patrón de bits 11000011 10100001. Nuevamente, para la salida, este patrón de bits se representa como el número hexadecimal 0xC3 0xA1:
>>> ua.encode('utf-8')
'\xc3\xa1'
Ejemplo 4
Lo siguiente codifica el punto de código Unicode U + 00E1 (que representa el carácter á) con Latin-1, lo que da como resultado el patrón de bits 11100001. Para la salida, este patrón de bits se representa como el número hexadecimal 0xE1, que por coincidencia es el mismo que el inicial punto de código U + 00E1:
>>> ua.encode('latin1')
'\xe1'
No hay relación entre el objeto Unicode ua
y la codificación Latin-1. Que el punto de código de á sea U + 00E1 y la codificación Latin-1 de á sea 0xE1 (si interpreta el patrón de bits de la codificación como un número binario) es una pura coincidencia.
unicode
, es sólo una abstracción de caracteres Unicode;unicode
se puede convertirstr
con alguna codificación (por ejemploutf-8
).