A principal fonte de problemas que tive ao trabalhar com strings unicode é quando você mistura strings codificadas em utf-8 com strings Unicode.
Por exemplo, considere os seguintes scripts.
two.py
# encoding: utf-8
name = 'helló wörld from two'
one.py
# encoding: utf-8
from __future__ import unicode_literals
import two
name = 'helló wörld from one'
print name + two.name
O resultado da execução python one.py
é:
Traceback (most recent call last):
File "one.py", line 5, in <module>
print name + two.name
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128)
Neste exemplo, two.name
é uma string codificada em utf-8 (não unicode), pois não foi importada unicode_literals
, e one.name
é uma string unicode. Quando você mistura os dois, o python tenta decodificar a string codificada (assumindo que seja ascii) e convertê-la para Unicode e falha. Funcionaria se você fizesse print name + two.name.decode('utf-8')
.
A mesma coisa pode acontecer se você codificar uma string e tentar misturá-las mais tarde. Por exemplo, isso funciona:
# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
Resultado:
DEBUG: <html><body>helló wörld</body></html>
Mas depois de adicionar import unicode_literals
NÃO:
# encoding: utf-8
from __future__ import unicode_literals
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
html = html.encode('utf-8')
print 'DEBUG: %s' % html
Resultado:
Traceback (most recent call last):
File "test.py", line 6, in <module>
print 'DEBUG: %s' % html
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 16: ordinal not in range(128)
Ele falha porque 'DEBUG: %s'
é uma string Unicode e, portanto, o python tenta decodificar html
. Algumas maneiras de corrigir a impressão são: print str('DEBUG: %s') % html
ou print 'DEBUG: %s' % html.decode('utf-8')
.
Espero que isso ajude você a entender as possíveis dificuldades ao usar strings Unicode.
decode()
soluções em vez das soluçõesstr()
ouencode()
: quanto mais você usar objetos Unicode, mais claro será o código, já que o que você deseja é manipular strings de caracteres, não matrizes de bytes com uma codificação implícita externamente.