2009-06-19 1 views
0

Первого раза делаю Python в каком-то время, и у меня возникают проблемы, делая простое сканирование файла, когда я запускаю следующий сценарий с Python 3.0.1,UnicodeDecodeError при чтении словарных слов файла с помощью сценария простого Python

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

Я получаю это исключение:

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 

строка в файле он взрывает на это «аргентинец», который не кажется необычным в любом случае.

Update: Я добавил,

encoding="iso-8559-1" 

к открытому() вызова, и это устранило проблему.

+0

Вы уверены, что вы не означает 'изо-8859-1'? Это кажется гораздо более распространенным явлением. Кроме того, \ xf3 является «-» в Asunción в iso-8859 (и это кодовая U + 00F3 в Unicode), но в UTF-8 он будет представлен как «\ xc3 \ xb3». – Malvolio

+0

@Malvolio: Это вполне возможно, я набрал неправильное имя кодировки ;-) –

ответ

1

Как вы определились с «позицией 1689-1692», какую строку в файле он взорвал? Эти числа будут смещениями в куске, который он пытается декодировать. Вам нужно было бы определить, какой кусок это было - как?

Попробуйте это в интерактивном режиме:

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

Я распечатал линию, когда она зациклилась над ними, и предположила, что она взорвалась строка после последней печати, когда было выбрано исключение. Но я попробовал то, что вы предложили, и, похоже, взорвался в другой момент, я получил: buf [9881-20: 9881 + 20] = b "as \ nAsturias \ nAsunci \ xf3n \ nAsunci \ xf3n \ nAswan \ n" , который действительно имеет забавный характер в «Асунсьоне». –

+0

(1) 9881-1689 == 8192 == multiple of chunk-size (2) Не похоже, DID взорвался при смещении файла 9881, подтвержденном экспериментом iconv. (3) не гарантирует, что stdout будет очищен при поднятии исключения, поэтому вы видели Аргентину (4), ни смешную, ни хари, ни забавные; попробуйте нейтральную терминологию типа «не-ASCII» (5), указав кодировку = «iso-8559-1», исправленная проблема, только если вы на 100% уверены, что это правильная кодировка - поскольку в этой кодировке используется весь 256-битный код точки, любой старый исполняемый файл или файл зашифрованных случайных байтов будет «успешно» декодироваться. –

+0

Спасибо за ваши технические комментарии, теперь это имеет смысл. (Хотя я попробую нейтральную терминологию, возможно, вы могли бы попытаться немного осветить? В конце концов, это сайт кодирования, а не международная дипломатия.) –

1

Вы можете проверить, что это действительно UTF-8? Способ сделать это дается в this SO question:

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

Есть другие способы сделать то же самое.

+0

В нем говорится: «iconv: незаконная входная последовательность в позиции 9881» –

Смежные вопросы