Por que UTF-8 e não ASCII para o Português? (PARTE II) :: Nilo Menezes
Codificação a usar em programas Python: por que UTF-8 é altamente recomendável
Codificações em geral e problemas causados e resolvidos por ela
Um bug do Python no Windows, quando o prompt é configurado para página 65001
É 7 bits, por isso vai de 0 a 127. Isso funcionava bem na década de 60… quando se enxugava bit para salvar tempo de transmissão de dados e armazenamento, muito antes dos torrents e afins :-D. A internacionalização disto ainda não estava em foco, aliás, ASCII significa Código Padrão Americano para Intercâmbio de Informação. Americano, diga-se estado-unidense.
Se você tem um arquivo com apenas duas letras AB uma após a outra, ele vai ocupar (seus dados) dois bytes no disco. O conteúdo binário dos dados do arquivo em disco são a sequência de bytes 0x41 e 0x42 (AB ou 65 e 66). É muito importante entender esta codificação antes de continuar lendo. Se você não entende que um A é guardado como o número 65, esqueça UTF-8… será preciso reler ou pedir ajuda a um amigo. Antigamente, curso de informática começava com sistema binário e tabela ASCII, hoje o primeiro programa já baixa páginas na Internet… mas a teoria de base é deixada para trás.
Para onde foi nosso Ã? Para lugar algum… ela estará lá, se usarmos a mesma página de código, ou seja a 850, que usamos para escrever.
Com apenas 3 bytes, já podemos ver o que pode acontecer… agora imagine com arquivos inteiros !
Como os computadores se espalharam pelo mundo, várias páginas foram criadas para o russo, grego, etc. Imagine então escrever um arquivo com partes em grego, partes em russo e chinês… uma catástrofe.
Outro problema é que línguas como o chinês precisam de mais de 256 símbolos para um texto normal, uma vez que o alfabeto deles é muito maior que o nosso. Surgem então tabelas de múltiplos bytes, onde mais de um byte era usado para cada caractere. Ainda assim, você precisava saber qual tabela multibyte foi usada… repetindo a confusão. Quem já trabalhou com Windows em C++ usando MBCS sabe a dor que isso causa…
Agora usamos 6 bytes para 3 caracteres. Ainda nem falamos de byte order ou de BOM… isso fica para outro dia :-D
Com 6 bytes para 3 letras, logo apareceram problemas de armazenamento de dados, pois os arquivos começaram a dobrar de tamanho e a tomar 2x mais tempo para serem transmitidos… em teoria. Uma forma mais enxuta de representar estes caracteres foi desenvolvida: o UTF-8.
C:\Users\nilo> \Python27\python.exe Desktop\test.py
SyntaxError: Non-ASCII character '\xc3' in file Desktop\test.py on
line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html
0x70 0x72 0x69 0x6E 0x74 0x20 0x22 0x41 0x42 0xC3 0x83 0x22 0x0D 0x0A                print "ABÃ"
C:\Users\nilo>\Python27\python.exe Desktop\test.py      ABÃ
Ué… mas a página 850 suporta o Ã. Por que o Python não imprimiu corretamente?
Ainda temos que resolver o problema da saída. No Python 2, as strings não são traduzidas de uma tabela para outra. Esta ambiguidade foi corrigida, no Python 3, com o tipo byte… mas ai já é outra história. Se você quer que o Python traduza de uma tabela para outra, use o prefixo u na string, de forma a indicar que é uma string unicode, codificada no formato utf-8, como dito no cabeçalho do programa.
0x70 0x72 0x69 0x6E 0x74 0x20 0x75 0x22 0x41 0x42 0xC3 0x83 0x22 0x0D 0x0A           print u"ABÃ"`
0x70 0x72 0x69 0x6E 0x74 0x20 0x75 0x22 0x41 0x42 0xC3 0x22 0x0D 0x0A                print u"ABÃ"
SyntaxError: (unicode error) 'utf8' codec can't decode byte 0xc3 in position 0: unexpected end of data