2013-08-23 9 views
5

W Pythonie 2.7 mam to:UnicodeDecodeError: 'utf8' kodek nie potrafi dekodować bajt "0xc3"

# -*- coding: utf-8 -*- 
from nltk.corpus import abc 
with open("abc.txt","w") as f: 
    f.write(" ".join(i.words())) 

I spróbuj czytać tego dokumentu w Pythonie 3:

with open("abc.txt", 'r', encoding='utf-8') as f: 
    f.read() 

aby uzyskać:

File "C:\Python32\lib\codecs.py", line 300, in decode 
    (result, consumed) = self._buffer_decode(data, self.errors, final) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xc3 in position 633096: invalid continuation byte 

Co zrobiłem źle? Notepad ++ wydaje się wskazywać, że dokumentem jest Unicode utf-8. Nawet jeśli próbuję przekonwertować dokument na ten format za pomocą Notepad ++ nadal dostaję ten błąd w pythonie 3, co jest dziwne, ponieważ czytam wiele innych zakodowanych w UTF-8 dokumentów bez żadnych problemów.

+0

Co "od" mówi o postaciach wokół tej pozycji? –

Odpowiedz

3

Zgaduję, że twoje dane wejściowe są zakodowane jako ISO-8859-2, który zawiera Ă jako 0xC3. Sprawdź kodowanie pliku wejściowego.

+0

Notepad ++ mówi, że dokument jest zakodowany jako UTF8 bez BOM – Baz

+8

@Baz Notepad ++ może odgadnąć źle. Istnieje * nie * niezawodny sposób na odgadnięcie kodowania. Każdy program czasami odgadnie złe kodowanie, dlatego zawsze należy * znać * kodowanie pliku. Spróbuj ponownie zapisać plik, czyniąc kodowanie utf-8 jawnym (np. Używając 'codecs.open' zamiast' open'). – Bakuriu

2

Na podstawie faktu, że Twój fragment Pythona 2.7 nie rzuca wyjątku, wywnioskowałbym, że i.words() zwraca sekwencję bajtów. Jest mało prawdopodobne, że zostaną zakodowane w UTF8 - domyślam się, że może to Łacina-1 lub coś podobnego. Następnie zapisujesz je do pliku. W tym momencie nie ma kodowania.

Prawdopodobnie musisz przekonwertować je na ciągi znaków Unicode, dla których musisz znać ich istniejące kodowanie, a następnie musisz zakodować je jako UTF-8 podczas pisania pliku.

Na przykład:

# -*- coding: utf-8 -*- 
from nltk.corpus import abc 
import codecs 
with codecs.open("abc.txt","w","utf-8") as f: 
    f.write(u" ".join(codecs.decode(word,"latin-1") for word in i.words())) 

Niektóre zauważa ponadto, w przypadku nie lada zamieszanie:

  • Linia -*- coding: utf-8 -*- odnosi się do kodowania wykorzystanego napisać skrypt Pythona siebie. Nie ma wpływu na dane wejściowe lub wyjściowe tego skryptu.
  • W języku Python 2.7 istnieją dwa rodzaje ciągów: bytestrings, które są ciągami bajtów o nieokreślonym kodowaniu i ciągami unicode, które są sekwencjami punktów kodowych Unicode. Bajstrzędy są najczęstsze i są tym, co dostajesz, jeśli używasz standardowej składni literowej o długości "abc". Ciągi Unicode są tym, co dostajesz, gdy używasz składni u"abc".
  • W Pythonie 2.7, jeśli po prostu użyjesz funkcji otwartej do otwarcia pliku i zapisania do niego bajtów testowych, kodowanie nie będzie miało miejsca. Bajty z analizy są zapisywane bezpośrednio do pliku. Jeśli spróbujesz napisać do niego ciągi znaków Unicode, otrzymasz wyjątek, jeśli zawierają znaki, które nie mogą być kodowane przez domyślny kodek (ASCII).
Powiązane problemy