Jestem bardzo zmieszany. Próbowałem zakodować, ale błąd powiedział can't decode...
.
>>> "你好".encode("utf8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
Wiem, jak uniknąć błędu z prefiksem „u” w ciągu. Zastanawiam się tylko, dlaczego błąd brzmi „nie można dekodować”, gdy wywołano kodowanie. Co robi Python pod maską?
"你好".decode('utf-8').encode('utf-8')
Zawsze koduj od Unicode do bajtów.
W tym kierunku możesz wybrać kodowanie .
Innym sposobem jest dekodowanie z bajtów do Unicode.
W tym kierunku musisz wiedzieć, jakie jest kodowanie .
Nie można tego wystarczająco podkreślić. Jeśli chcesz uniknąć grania w Unicode „whack-a-mole”, ważne jest, aby zrozumieć, co dzieje się na poziomie danych. Tutaj jest wyjaśnione w inny sposób:
decode
.encode
.Teraz, widząc
.encode
ciąg bajtów, Python 2 najpierw próbuje niejawnie przekonwertować go na tekst (unicode
obiekt). Podobnie, widząc.decode
ciąg znaków Unicode, Python 2 niejawnie próbuje przekonwertować go na bajty (str
obiekt).Te niejawne konwersje są powodem, dla którego możesz uzyskać, gdy zadzwonisz . Dzieje się tak, ponieważ kodowanie zwykle akceptuje parametr typu ; podczas odbierania parametru następuje niejawne dekodowanie do obiektu typu przed ponownym zakodowaniem go za pomocą innego kodowania. Ta konwersja wybiera domyślny dekoder „ascii” † , podając błąd dekodowania wewnątrz kodera.
Unicode
Decode
Error
encode
unicode
str
unicode
W rzeczywistości w Pythonie 3 metody
str.decode
ibytes.encode
nawet nie istnieją. Ich usunięcie było [kontrowersyjną] próbą uniknięcia tego powszechnego zamieszania.† ... lub cokolwiek
sys.getdefaultencoding()
wspomina kod; zwykle jest to „ascii”źródło
_
odnosi się do poprzedniej wartości 2. ponieważ jest to pytanie Python-2.x.Możesz tego spróbować
Lub
Możesz także spróbować śledzić
Dodaj następujący wiersz u góry pliku .py.
źródło
Jeśli używasz Pythona <3, musisz powiedzieć interpreterowi, że twój literał ciągu to Unicode, poprzedzając go
u
:Dalsza lektura : Unicode HOWTO .
źródło
Używasz
u"你好".encode('utf8')
do kodowania ciągu znaków Unicode. Ale jeśli chcesz to przedstawić"你好"
, powinieneś to zdekodować. Tak jak:Dostaniesz to, czego chcesz. Może powinieneś dowiedzieć się więcej o kodowaniu i dekodowaniu.
źródło
Jeśli masz do czynienia z Unicode, czasami zamiast tego
encode('utf-8')
możesz spróbować zignorować znaki specjalne, nplub jak
something.decode('unicode_escape').encode('ascii','ignore')
sugerowano tutaj .Niezbyt przydatne w tym przykładzie, ale może działać lepiej w innych scenariuszach, gdy nie można przekonwertować niektórych znaków specjalnych.
Alternatywnie możesz rozważyć zastąpienie określonego znaku za pomocą
replace()
.źródło
Jeśli uruchamiasz interpreter Pythona z powłoki na Linuksie lub podobnych systemach (BSD, nie jestem pewien co do Maca), powinieneś również sprawdzić domyślne kodowanie powłoki.
Zadzwoń
locale charmap
z powłoki (nie interpretera Pythona) i powinieneś zobaczyćJeśli tak nie jest, a widzisz coś innego, np
Python (przynajmniej w niektórych przypadkach, takich jak mój) odziedziczy kodowanie powłoki i nie będzie w stanie wydrukować (niektórych? Wszystkich?) Znaków Unicode. Własne domyślne kodowanie Pythona, które można zobaczyć i sterować za pomocą,
sys.getdefaultencoding()
isys.setdefaultencoding()
jest w tym przypadku ignorowane.Jeśli okaże się, że masz ten problem, możesz go naprawić, korzystając z pliku
(Lub alternatywnie wybierz dowolną mapę klawiszy zamiast en_EN.) Możesz także edytować
/etc/locale.conf
(lub dowolny plik zarządzający definicją ustawień regionalnych w twoim systemie), aby to poprawić.źródło