Por que o item abaixo está falhando? e por que ele é bem-sucedido com "latin-1" codec?
o = "a test of \xe9 char" #I want this to remain a string as this is what I am receiving
v = o.decode("utf-8")
resultados em:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\encodings\utf_8.py",
line 16, in decode
return codecs.utf_8_decode(input, errors, True) UnicodeDecodeError:
'utf8' codec can't decode byte 0xe9 in position 10: invalid continuation byte
Em binário, 0xE9 parece 1110 1001
. Se você ler sobre UTF-8 na Wikipedia, você verá que tal byte deve ser seguido por dois do formulário 10xx xxxx
. Então, por exemplo:
>>> b'\xe9\x80\x80'.decode('utf-8')
u'\u9000'
Mas essa é apenas a causa mecânica da excepção. Neste caso, você tem uma corda que é quase certamente codificada no latim 1. Você pode ver como UTF-8 e latim 1 parecem diferentes:
>>> u'\xe9'.encode('utf-8')
b'\xc3\xa9'
>>> u'\xe9'.encode('latin-1')
b'\xe9'
(Nota, I'm usando uma mistura de representação Python 2 e 3 aqui. A entrada é válida em qualquer versão do Python, mas é improvável que o seu intérprete Python mostre tanto strings unicode como byte desta forma).
É inválido UTF-8. Esse carácter é o carácter e-acute em ISO-Latin1, e é por isso que é bem sucedido com esse conjunto de códigos.
Se você não'não sabe os códigos que você'está recebendo strings, você'está com um pouco de problema. Seria melhor se um único conjunto de códigos (esperançosamente UTF-8) fosse escolhido para o seu protocolo/aplicação e então você'apenas rejeitaria aqueles que não't decodificaram.
Se você pode't fazer isso, você'vai precisar de heurística.
Porque UTF-8 é multibyte e não há nenhum char correspondente à sua combinação de `\xe9' mais o espaço seguinte.
Por que deve ter sucesso em ambos utf-8 e latin-1?
Aqui como a mesma frase deve estar em utf-8:
>>> o.decode('latin-1').encode("utf-8")
'a test of \xc3\xa9 char'