Unicode e codificações são coisas completamente diferentes e não relacionadas.
Unicode
Atribui um ID numérico a cada caractere:
- 0x41 → A
- 0xE1 → á
- 0x414 → Д
Portanto, o Unicode atribui o número 0x41 a A, 0xE1 a á e 0x414 a Д.
Até a pequena seta → que usei tem seu número Unicode, é 0x2192. E mesmo os emojis têm seus números Unicode, 😂 é 0x1F602.
Você pode pesquisar os números Unicode de todos os caracteres nesta tabela . Em particular, você pode encontrar os primeiros três caracteres acima aqui , a seta aqui e o emoji aqui .
Esses números atribuídos a todos os caracteres por Unicode são chamados de pontos de código .
O objetivo de tudo isso é fornecer um meio de se referir inequivocamente a cada personagem. Por exemplo, se estou falando sobre 😂, em vez de dizer "você sabe, esse emoji rindo com lágrimas" , posso apenas dizer, ponto de código Unicode 0x1F602 . Mais fácil, certo?
Observe que os pontos de código Unicode geralmente são formatados com um inicial e U+
, em seguida, o valor numérico hexadecimal preenchido com pelo menos 4 dígitos. Portanto, os exemplos acima seriam U + 0041, U + 00E1, U + 0414, U + 2192, U + 1F602.
Os pontos de código Unicode variam de U + 0000 a U + 10FFFF. Isso é 1.114.112 números. 2.048 desses números são usados para substitutos , portanto, permanecem 1.112.064. Isso significa que o Unicode pode atribuir um ID exclusivo (ponto de código) a 1.112.064 caracteres distintos. Nem todos esses pontos de código foram atribuídos a um caractere ainda, e o Unicode é estendido continuamente (por exemplo, quando novos emojis são introduzidos).
O importante a lembrar é que tudo o que o Unicode faz é atribuir um ID numérico, chamado ponto de código, a cada caractere para uma referência fácil e inequívoca.
Codificações
Mapeie caracteres para padrões de bits.
Esses padrões de bits são usados para representar os caracteres na memória do computador ou no disco.
Existem muitas codificações diferentes que abrangem diferentes subconjuntos de caracteres. No mundo de língua inglesa, as codificações mais comuns são as seguintes:
Mapas de 128 caracteres (pontos de código U + 0000 a U + 007F) para padrões de bits de comprimento 7.
Exemplo:
Você pode ver todos os mapeamentos nesta tabela .
Mapas de 191 caracteres (pontos de código U + 0020 para U + 007E e U + 00A0 para U + 00FF) para padrões de bits de comprimento 8.
Exemplo:
- a → 01100001 (0x61)
- á → 11100001 (0xE1)
Você pode ver todos os mapeamentos nesta tabela .
Mapas 1.112.064 caracteres (todos os pontos de código Unicode existentes) para padrões de bits de comprimento 8, 16, 24 ou 32 bits (ou seja, 1, 2, 3 ou 4 bytes).
Exemplo:
- a → 01100001 (0x61)
- á → 11000011 10100001 (0xC3 0xA1)
- ≠ → 11100010 10001001 10100000 (0xE2 0x89 0xA0)
- 😂 → 11110000 10011111 10011000 10000010 (0xF0 0x9F 0x98 0x82)
A maneira como o UTF-8 codifica caracteres para sequências de bits é muito bem descrita aqui .
Unicode e codificações
Observando os exemplos acima, fica claro como o Unicode é útil.
Por exemplo, se eu sou Latin-1 e desejo explicar minha codificação de á, não preciso dizer:
"Codifico isso a com um aigu (ou como você chama essa barra ascendente) como 11100001"
Mas posso apenas dizer:
"Codifico U + 00E1 como 11100001"
E se eu for UTF-8 , posso dizer:
"Eu, por sua vez, codifico U + 00E1 como 11000011 10100001"
E é inequivocamente claro para todos a qual personagem queremos dizer.
Agora, para a confusão que muitas vezes surge
É verdade que às vezes o padrão de bits de uma codificação, se você interpretá-lo como um número binário, é o mesmo que o ponto de código Unicode desse caractere.
Por exemplo:
- ASCII codifica a como 1100001, que você pode interpretar como o número hexadecimal 0x61 , e o ponto de código Unicode de a é U + 0061 .
- Latin-1 codifica á como 11100001, que você pode interpretar como o número hexadecimal 0xE1 , e o ponto de código Unicode de á é U + 00E1 .
Claro, isso foi arranjado assim de propósito por conveniência. Mas você deve olhar para isso como uma pura coincidência . O padrão de bits usado para representar um caractere na memória não está vinculado de forma alguma ao ponto de código Unicode desse caractere.
Ninguém diz que você deve interpretar uma string de bits como 11100001 como um número binário. Basta olhar para ele como a sequência de bits que Latin-1 usa para codificar o caractere á .
De volta à sua pergunta
A codificação usada pelo seu interpretador Python é UTF-8 .
Aqui está o que está acontecendo em seus exemplos:
Exemplo 1
O seguinte codifica o caractere á em UTF-8. Isso resulta na sequência de bits 11000011 10100001, que é salva na variável a
.
>>> a = 'á'
Quando você olha para o valor de a
, seu conteúdo 11000011 10100001 é formatado como o número hexadecimal 0xC3 0xA1 e gerado como '\xc3\xa1'
:
>>> a
'\xc3\xa1'
Exemplo 2
O seguinte salva o ponto de código Unicode de á, que é U + 00E1, na variável ua
(não sabemos qual formato de dados o Python usa internamente para representar o ponto de código U + 00E1 na memória e isso não é importante para nós):
>>> ua = u'á'
Quando você olha para o valor de ua
, Python informa que ele contém o ponto de código U + 00E1:
>>> ua
u'\xe1'
Exemplo 3
O seguinte codifica o ponto de código Unicode U + 00E1 (representando o caractere á) com UTF-8, o que resulta no padrão de bits 11000011 10100001. Novamente, para a saída, este padrão de bits é representado como o número hexadecimal 0xC3 0xA1:
>>> ua.encode('utf-8')
'\xc3\xa1'
Exemplo 4
O seguinte codifica o ponto de código Unicode U + 00E1 (representando o caractere á) com Latin-1, o que resulta no padrão de bits 11100001. Para a saída, este padrão de bits é representado como o número hexadecimal 0xE1, que por coincidência é o mesmo que o inicial ponto de código U + 00E1:
>>> ua.encode('latin1')
'\xe1'
Não há relação entre o objeto Unicode ua
e a codificação Latin-1. Que o ponto de código de á seja U + 00E1 e a codificação Latin-1 de á seja 0xE1 (se você interpretar o padrão de bits da codificação como um número binário) é pura coincidência.
unicode
, é apenas uma abstração de caracteres Unicode;unicode
pode ser convertido parastr
com alguma codificação (por exemploutf-8
).