Python: tudo o que voc� j� deveria saber sobre Unicode


Logotipo Python

�lvaro Justen aka Turicas

8� encontro da Comunidade Python Brasileira
Rio de Janeiro
23/11/2012

Álvaro Justen, prazer!

{twitter.com, github.com, youtube.com}/turicas
turicas.info
alvarojusten@gmail.com


emap.fgv.br
github.com/NAMD


www.CursoDeArduino.com.br

Agora vocês...

Encoding errors everywhere
Encoding errors everywhere

Tudo começou com um ônibus...


Ônibus da Salutaris
  • Mas eu aprendi a não usar mais acentos nessa empresa!

Porém os erros continuaram acontecendo... :-/



Traveler info

E não só comigo...



Bilhete Dukão

Erros em todos os lugares



Erro no email

Até no Facebook!



Erro App Facebook

Nem as URLs passaram desapercebidas...


URL error

Nem as URLs passaram desapercebidas... [2]


URL error 2
Logotipo Unicode

Unicode Consortium

Ian Albert: impressão da tabela Unicode

Unicode printed

Unicode [2]

Como resolver isso?

.encode/.decode

Python 2!

Entendendo o que está codificado

Python 2!

>>> nome = 'álvaro'
>>> nome2 = u'álvaro'

>>> print len(nome), type(nome)
>>> print nome[0], nome[1]
>>> print len(nome2), type(nome2)
>>> print nome2[0], nome2[1]

>>> print nome == nome2
>>> print nome.decode('utf-8') == nome2

>>> print nome.upper(), type(nome.upper())
>>> maiusculo = nome.decode('utf-8').upper()
>>> print maiusculo, type(maiusculo)

ASCII

ASCII [2]

UTF-8

UTF-8 [2]

Tabelas incompatíveis

Binariamente e em tamanho

Tabela 1
Símbolo Código
A 1
B 2
C 3
D 4
Tabela 2
Símbolo Código
A 4
B 3
C 2
D 1
E 5
>>> print 'python'.decode('utf-8').encode('ascii')
>>> print 'abcdefghijklmnopqrstuvwxyz'.decode('cp1140')
>>> print 'abcdefghijklmnopqrstuvwxyz'.decode('rot13')
>>> print 'abcdefghijklmnopqrstuvwxyz'.encode('base64')

Tabelas incompatíveis [2]

>>> print chr(226).decode('iso-8859-15')
â
>>> print chr(226).decode('iso-8859-7')
β
>>> print chr(226).decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in 
  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe2 in position 0: unexpected end of data
No mundo real...

Fazendo slugs direito

Fazendo slugs direito [2]

Parâmetro 'errors':

>>> print new_string.encode('ascii', 'replace') # default: 'strict'
A?lvaro
>>> print new_string.encode('ascii', 'xmlcharrefreplace')
A&#769;lvaro
>>> print new_string.encode('ascii', 'backslashreplace')
A\u0301lvaro

base64: encodando encodados

aka "ASCII armor"

>>> u'Álvaro'
u'\xc1lvaro'
>>> u'Álvaro'.encode('utf-8').encode('base64')
'w4FsdmFybw==\n'
>>> 'w4FsdmFybw=='.decode('base64')
'\xc3\x81lvaro'
>>> 'w4FsdmFybw=='.decode('base64').decode('utf8')
u'\xc1lvaro'

Cuidado com a Apple!

>>> eh = unichr(0x0065) + \
         unichr(0x0301)
>>> eh2 = unichr(0x00e9)
>>> print eh, eh2
>>> print eh == eh2 # WTF?
>>> print eh.encode('utf8')
>>> print eh2.encode('utf8')
>>> # composed
>>> print normalize('NFC', eh)
>>> print normalize('NFC', eh2)
>>> # decomposed
>>> print normalize('NFKD', eh)
>>> print normalize('NFKD', eh2)

E no Python 3? #F7U13

Dicas

Dicas [2]

Dicas [3]

Referências

Curso online - PyCursos + PingMind

?

{twitter.com, github.com, youtube.com}/turicas
turicas.info
alvarojusten@gmail.com
turicas.info/slides/python-unicode