2011-01-25 20 views
7

Próbuję wydrukować ciąg znaków Unicode bez określonego kodu szykującego w nim. Chwytam te dane z Facebooka, który ma typ kodowania w nagłówkach html UTF-8. Kiedy wypisuję typ - mówi on o unicode, ale kiedy próbuję go zdekodować, uciekając unicode, mówi, że jest błąd kodowania. Dlaczego próbuje kodować, gdy używam metody dekodowania?Funkcja dekodowania próbuje kodować Python

Kod

a='really long string of unicode html text that i wont reprint' 
print type(a) 
>>> <type 'unicode'> 
print a.decode('unicode-escape') 
>>> Traceback (most recent call last): 
    File "scfbp.py", line 203, in myFunctionPage 
    print a.decode('unicode-escape') 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 1945: ordinal not in range(128) 

Odpowiedz

8

To nie dekodowania, który jest wadliwa. Dzieje się tak, ponieważ próbujesz wyświetlić wynik na konsoli. Kiedy używasz print, koduje ciąg znaków przy użyciu domyślnego kodowania, które jest ASCII. Nie używaj drukowania i powinno działać.

 
>>> a=u'really long string containing \\u20ac and some other text' 
>>> type(a) 
<type 'unicode'> 
>>> a.decode('unicode-escape') 
u'really long string containing \u20ac and some other text' 
>>> print a.decode('unicode-escape') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 30: ordinal not in range(128) 

Polecam używanie IDLE lub innego interpretera, który może wyprowadzać Unicode, wtedy nie dostaniesz tego problemu.


Aktualizacja: Zauważ, że to nie jest taka sama jak situtation z jednym mniejszym backslashem, gdzie zawiedzie podczas dekodowania, ale z tym samym komunikatem o błędzie:

 
>>> a=u'really long string containing \u20ac and some other text' 
>>> type(a) 
<type 'unicode'> 
>>> a.decode('unicode-escape') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 30: ordinal not in range(128) 
+0

To nie jest powód jego błędu. Próbuje odszyfrować obiekt Unicode. Ponieważ dekodujesz dane binarne do danych unicode, Python 2 najpierw * zakoduje * to, co robi z kodem ASCII. To się nie udaje. –

+0

@Lennart Regebro: Właściwie podejrzewam, że rzeczywisty typ jego łańcucha to 'str', a nie' unicode'. Zobacz, jak on inicjuje ciąg znaków - zauważ, że nie ma "u". Myślę, że to, co ma, nie jest łańcuchem unicode, ale łańcuchem * unikatowym * (nie tym samym!). To właśnie on próbuje rozszyfrować do unicode. Jeśli moja teoria jest właściwa, myślę, że ta odpowiedź jest prawdziwa. –

+0

@Mark Byers: To prawda, to niespójne, ale brak u jest łatwiejsze niż wpisanie niewłaściwego typu. :) A błąd jest zgodny z tym, co robi. W przypadku dekodowania obiektu unicode pojawia się błąd kodowania. –

3

Podczas drukowania do konsola Python próbuje zakodować (przekonwertować) ciąg znaków na zestaw znaków terminalu. Jeśli to nie jest UTF-8, lub coś, co nie mapuje wszystkich znaków w łańcuchu, to będzie jęczeć i rzucać wyjątek.

To drażni mnie od czasu do czasu, gdy wykonuję szybkie przetwarzanie danych, na przykład za pomocą znaków tureckich.

Jeśli używasz python.exe przez wiersz poleceń systemu Windows, możesz znaleźć kilka rozwiązań tutaj: What encoding/code page is cmd.exe using. Zasadniczo możesz zmienić stronę kodową za pomocą chcp, ale jest to dość uciążliwe. Podążałbym za Mark's advice i używałbym czegoś takiego jak IDLE.

+1

Chcesz wyjaśnić wartość -1? – Skurmedel

1
>>> print type(a) 
<type 'unicode'> 
>>> a.decode('unicode-escape') 

Dlaczego próbuje zakodować kiedy użyć metody dekodowania?

Bo dekodować do Unicode i zakodować z. Po prostu próbowałeś dekodować ciąg Unicode do Unicode. Pierwszą rzeczą, którą następnie robi, jest próba przekonwertowania go na ciąg znaków z kodem ASCII. Dlatego otrzymujesz:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2110' in position 3: ordinal not in range(128) 

Pamiętaj: Unicode nie jest kodowaniem. Cała reszta jest taka, jak ascii, utf8, latin-1 itd.

To niejawne kodowanie zniknęło w Pythonie 3, btw, ponieważ dezorientuje ludzi.

Powiązane problemy