Więc mam message
który jest odczytywany z pliku o nieznanym kodowaniu. Chcę wysłać na stronę do wyświetlenia. Dużo zmagałem się z UnicodeErrors i przeszedłem wiele pytań i odpowiedzi na StackOverflow i myślę, że dobrze rozumiem jak działa Unicode i kodowanie.
try :
return message.decode(encoding="utf-8")
except:
try:
return message.decode(encoding="latin-1")
except:
try:
print("Unable to entirely decode in latin or utf-8, will replace error characters with "?"")
return message.decode(encoding="utf-8", errors="replace")
Zwracana wiadomość jest następnie wrzucana do JSON i wysyłana na front end.
Przyjąłem to, ponieważ używam errors="replace"
na ostatnim try except
że zamierzam uniknąć wyjątków kosztem posiadania kilku „?” znaki na moim wyświetlaczu. Dopuszczalny koszt.
Wydaje się jednak, że byłem zbyt pełen nadziei, a dla niektórych plików nadal otrzymuję UnicodeDecodeException
powiedzenie „kodeki ascii nie mogą dekodować” dla niektórych postaci. Dlaczego nie? errors="replace"
po prostu się tym zajmij?
(również jako dodatkowe pytanie, co ascii ma wspólnego z tym?
Odpowiedzi:
1 dla odpowiedzi № 1Nie powinieneś dostać UnicodeDecodeError
z errors="replace"
. Również str.decode("latin-1")
nigdy nie powinien zawieść, ponieważ ISO-8859-1 ma poprawne odwzorowanie znaków dla każdej możliwej sekwencji bajtów.
Podejrzewam, że to message
jest już unicode
ciąg, nie bajty. Tekst Unicode został już „zdekodowany” z bajtów i nie można go już odkodować.
Kiedy zadzwonisz .decode()
a unicode
ciąg, Python 2 stara się być pomocny i decyduje się kodować ciąg Unicode z powrotem do bajtów (przy użyciu domyślnego kodowania), dzięki czemu masz coś, co naprawdę możesz dekodować. Ten niejawny krok kodowania doesn "t posługiwać się errors="replace"
, więc jeśli w łańcuchu Unicode są jakieś znaki, które nie są w domyślnym kodowaniu (prawdopodobnie ASCII), otrzymasz UnicodeEncodeError
.
(Python 3 już tego nie robi, ponieważ jest strasznie mylący)
Sprawdź typ message
i zakładając, że rzeczywiście tak jest Unicode
, wróć tam, aby znaleźć miejsce, w którym zostało zdekodowane (prawdopodobnie niejawnie), aby zastąpić je prawidłowym dekodowaniem.
0 dla odpowiedzi nr 2
dekodowanie z błędem zastąpienie implementuje obsługę błędów „zastąp” (dla kodowanie tekstu tylko): zastępuje „?” dla błędów kodowania (do zakodowania przez kodek) i „ufffd” (znak zastępczy Unicode) dla błędów dekodowania
kodowanie tekstu oznacza „kodek, który koduje ciągi Unicode na bajty”.
być może twoje dane są zniekształcone - powinieneś spróbować „zignorować” obsługę błędów, w przypadku gdy zniekształcone dane są ignorowane, a kodowanie lub dekodowanie jest kontynuowane bez powiadomienia.
message.decode(encoding="utf-8", errors="ignore")