2009-06-19 9 views
0

première fois faire Python dans un certain temps, et je vais avoir du mal à faire une analyse simple d'un fichier quand je lance le script suivant avec Python 3.0.1,UnicodeDecodeError lors de la lecture des mots du dictionnaire fichier avec un script Python simple,

with open("/usr/share/dict/words", 'r') as f: 
    for line in f: 
     pass 

Je reçois cette exception:

Traceback (most recent call last): 
    File "/home/matt/install/test.py", line 2, in <module> 
    for line in f: 
    File "/home/matt/install/root/lib/python3.0/io.py", line 1744, in __next__ 
    line = self.readline() 
    File "/home/matt/install/root/lib/python3.0/io.py", line 1817, in readline 
    while self._read_chunk(): 
    File "/home/matt/install/root/lib/python3.0/io.py", line 1565, in _read_chunk 
    self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) 
    File "/home/matt/install/root/lib/python3.0/io.py", line 1299, in decode 
    output = self.decoder.decode(input, final=final) 
    File "/home/matt/install/root/lib/python3.0/codecs.py", line 300, in decode 
    (result, consumed) = self._buffer_decode(data, self.errors, final) 
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 1689-1692: invalid data 

la ligne dans le fichier, il explose sur est « argentin », ce qui ne semble pas être inhabituel en aucune façon.

Mise à jour: J'ajouté,

encoding="iso-8559-1" 

à l'appel open(), et il résolu le problème. Pouvez-vous vérifier pour vous assurer qu'il est valide UTF-8?

+0

Etes-vous sûr que vous ne vouliez pas dire 'iso-8859-1'? Cela semble être beaucoup plus commun. De plus, \ xf3 est "ó" dans Asunción dans iso-8859 (et c'est le code-code U + 00F3 dans Unicode), mais dans UTF-8, il serait représenté par "\ xc3 \ xb3". – Malvolio

+0

@Malvolio: Il est tout à fait possible que j'ai tapé le nom de codage faux ;-) –

Répondre

1

Comment avez-vous déterminé à partir de "position 1689-1692" quelle ligne dans le fichier sur lequel il a explosé? Ces nombres seraient des offsets dans le morceau qu'il essaie de décoder. Vous auriez dû déterminer quel morceau c'était - comment?

Essayez ceci à l'invite interactive:

buf = open('the_file', 'rb').read() 
len(buf) 
ubuf = buf.decode('utf8') 
# splat ... but it will give you the byte offset into the file 
buf[offset-50:60] # should show you where/what the problem is 
# By the way, from the error message, looks like a bad 
# FOUR-byte UTF-8 character ... interesting 
+0

Je l'ai fait imprimer la ligne comme il boucle sur eux, et supposé qu'il a explosé sur la ligne après le dernier imprimé lorsque l'exception a été levée. Mais j'ai essayé ce que vous avez suggéré, et il semble exploser à un point différent, j'ai: buf [9881-20: 9881 + 20] = b "as \ nAsturias \ nAsunci \ xf3n \ nAsunci \ xf3n \ nAswan \ n" , qui a en effet un drôle de caractère dans "Asunción". –

+0

(1) 9881-1689 == 8192 == multiple de taille de morceau (2) ne semble pas, DID exploser au fichier offset 9881, confirmé par l'expérience iconv. (3) aucune garantie que stdout est vidé lorsque l'exception est levée, c'est pourquoi vous avez vu l'Argentine (4) ni drôle-haha ni drôle-particulier; essayez une terminologie neutre comme "non-ASCII" (5) en spécifiant encoding = "iso-8559-1" pour résoudre le problème uniquement si vous êtes sûr à 100% que le codage est correct car ce codage utilise le code 256 bits à 8 bits points, tout ancien exécutable ou fichier d'octets aléatoires cryptés "décompose" avec succès. –

+0

Merci pour vos commentaires techniques, c'est logique. (Tandis que j'essaierai la terminologie neutre, peut-être pourriez-vous essayer d'alléger un peu? Après tout, ceci est un site Web de codage, pas diplomatie internationale.) –

1

Une façon de le faire est donnée à this SO question:

iconv -f UTF-8 /usr/share/dict/words -o /dev/null 

Il y a d'autres façons de faire la même chose.

+0

Il dit, "iconv: séquence d'entrée illégale à la position 9881" –

Questions connexes