Pourquoi l'élément ci-dessous est-il défaillant? et pourquoi réussit-il avec le codec "latin-1"?
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")
résulte en:
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
En binaire, 0xE9 ressemble à 1110 1001
. Si vous lisez à propos de TF-8 sur Wikipedia , vous verrez qu’un tel octet doit être suivi de deux de la forme 10xx xxxx
. Donc, par exemple:
>>> b'\xe9\x80\x80'.decode('utf-8')
u'\u9000'
Mais c’est la cause mécanique de l’exception. Dans ce cas, vous avez une chaîne codée presque certainement en latin 1. Vous pouvez voir en quoi UTF-8 et latin 1 ont un aspect différent:
>>> u'\xe9'.encode('utf-8')
b'\xc3\xa9'
>>> u'\xe9'.encode('latin-1')
b'\xe9'
(Remarque: j'utilise un mélange de Python 2 et de représentations 3 ici. L'entrée est valide dans n'importe quelle version de Python, mais votre interprète Python n'affiche pas réellement les deux caractères unicode. et byte les chaînes de cette façon.)
J'ai eu la même erreur lorsque j'ai essayé d'ouvrir un fichier csv avec la méthode pandas read_csv.
La solution a été de changer le codage en 'latin-1':
pd.read_csv('ml-100k/u.item', sep='|', names=m_cols , encoding='latin-1')
Il est invalide UTF-8. Ce caractère est le caractère e-aigu dans ISO-Latin1, raison pour laquelle il réussit avec ce jeu de codes.
Si vous ne connaissez pas le jeu de codes dans lequel vous recevez des chaînes, vous avez quelques problèmes. Il serait préférable qu'un seul jeu de codes (UTF-8, espérons-le) soit choisi pour votre protocole/votre application et que vous refusiez simplement ceux qui ne décodent pas.
Si vous ne pouvez pas faire cela, vous aurez besoin d'heuristiques.
Parce que UTF-8 est multi-octets et qu'il n'y a pas de caractère correspondant à votre combinaison de \xe9
plus d'espace suivant.
Pourquoi devrait-il réussir les deux utf-8 et latin-1?
Voici comment la même phrase devrait être dans utf-8:
>>> o.decode('latin-1').encode("utf-8")
'a test of \xc3\xa9 char'
Si cette erreur se produit lors de la manipulation d'un fichier qui vient d'être ouvert, vérifiez si vous l'avez ouvert en mode 'rb'
Cela m'est également arrivé pendant que je lisais du texte contenant l'hébreu à partir d'un fichier .txt
.
J'ai cliqué sur: file -> save as
et j'ai enregistré ce fichier au format UTF-8
.