it-swarm.com.de

Python - "Ascii" -Codec kann kein Byte decodieren

Ich bin wirklich verwirrt. Ich habe versucht zu kodieren, aber der Fehler sagte 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)

Ich weiß, wie man den Fehler mit dem Präfix "u" in der Zeichenfolge vermeidet. Ich frage mich nur, warum der Fehler "kann nicht decodieren", wenn encode aufgerufen wurde. Was macht Python unter der Haube?

106
thoslin
"你好".encode('utf-8')

encode konvertiert ein Unicode-Objekt in ein string-Objekt. Aber hier haben Sie es für ein string-Objekt aufgerufen (weil Sie kein u haben). Daher muss Python zuerst die string in ein unicode-Objekt konvertieren. Also macht es das Äquivalent von

"你好".decode().encode('utf-8')

Die Decodierung schlägt jedoch fehl, da die Zeichenfolge nicht gültig ist. Deswegen bekommst du eine Beschwerde, dass man nicht entschlüsseln kann.

151
Winston Ewert

Immer encode von Unicode zu Bytes.
In dieser Richtung wählen Sie Sie wählen die Kodierung

>>> u"你好".encode("utf8")
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> print _
你好

Der andere Weg ist die Decodierung von Bytes bis Unicode.
In dieser Richtung müssen Sie wissen, was die Kodierung ist .

>>> bytes = '\xe4\xbd\xa0\xe5\xa5\xbd'
>>> print bytes
你好
>>> bytes.decode('utf-8')
u'\u4f60\u597d'
>>> print _
你好

Dieser Punkt kann nicht genug betont werden. Wenn Sie vermeiden möchten, Unicode "Whack-a-Mole" zu spielen, müssen Sie wissen, was auf Datenebene geschieht. Hier wird es anders erklärt:

  • Ein Unicode-Objekt ist bereits dekodiert. Sie möchten niemals decode für dieses Objekt aufrufen.
  • Ein Bytestring-Objekt ist bereits codiert. Sie möchten niemals encode für das Objekt aufrufen.

Wenn nun .encode in einem Byte-String angezeigt wird, versucht Python 2 zuerst, ihn implizit in Text (ein unicode-Objekt) zu konvertieren. Auf ähnliche Weise versucht Python 2 beim Anzeigen von .decode in einer Unicode-Zeichenfolge implizit, es in Bytes (ein str-Objekt) zu konvertieren. 

Diese impliziten Konvertierungen sind der Grund, warum Sie UnicodeDecodeError erhalten können, wenn Sieencodeaufgerufen haben. Dies liegt daran, dass die Kodierung normalerweise einen Parameter des Typs unicode akzeptiert. Beim Empfang eines str-Parameters erfolgt eine implizite Dekodierung in ein Objekt vom Typ unicode, bevor es mit einer anderen Kodierung erneut kodiert wird. Diese Konvertierung wählt einen Standard-ASCII-Decoder aus, gibt Ihnen den Decodierungsfehler in einem Encoder.

In Python 3 gibt es die Methoden str.decode und bytes.encode gar nicht. Ihre Entfernung war ein [umstrittener] Versuch, diese allgemeine Verwirrung zu vermeiden.

... oder was auch immer die sys.getdefaultencoding()-Codierung erwähnt; normalerweise ist dies 'ascii'

48
wim

Du kannst es versuchen  

import sys
reload(sys)
sys.setdefaultencoding("utf-8")

Oder

Sie können auch versuchen,

Fügen Sie die folgende Zeile oben in Ihrer .py-Datei ein.

# -*- coding: utf-8 -*- 
36
Dadaso Zanzane

Wenn Sie Python <3 verwenden, müssen Sie dem Interpreter mitteilen, dass Ihr String-Literal Unicode ist, indem Sie ihm eine u voranstellen:

Python 2.7.2 (default, Jan 14 2012, 23:14:09) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> "你好".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)
>>> u"你好".encode("utf8")
'\xe4\xbd\xa0\xe5\xa5\xbd'

Lesen Sie weiter: Unicode HOWTO .

8
Johnsyweb

Sie verwenden u"你好".encode('utf8'), um eine Unicode-Zeichenfolge zu codieren Wenn Sie jedoch "你好" darstellen möchten, müssen Sie ihn dekodieren. So wie:

"你好".decode("utf8")

Sie werden bekommen, was Sie wollen. Vielleicht sollten Sie mehr über das Kodieren und Dekodieren lernen.

3
Qingtian

Falls Sie mit Unicode zu tun haben, können Sie anstelle von encode('utf-8') auch versuchen, die Sonderzeichen zu ignorieren, z.

"你好".encode('ascii','ignore')

oder als something.decode('unicode_escape').encode('ascii','ignore'), wie hier vorgeschlagen .

In diesem Beispiel nicht besonders nützlich, kann jedoch in anderen Szenarien besser funktionieren, wenn einige Sonderzeichen nicht konvertiert werden können.

Alternativ können Sie bestimmte Zeichen mit replace() ersetzen.

3
kenorb

Wenn Sie den Python-Interpreter von einer Shell unter Linux oder ähnlichen Systemen (BSD, nicht sicher über Mac) starten, sollten Sie auch die Standardcodierung für die Shell überprüfen. 

Rufen Sie locale charmap von der Shell (nicht vom Python-Interpreter) auf und Sie sollten es sehen

[[email protected] dir] $ locale charmap
UTF-8
[[email protected] dir] $ 

Wenn dies nicht der Fall ist und Sie etwas anderes sehen, z. 

[[email protected] dir] $ locale charmap
ANSI_X3.4-1968
[[email protected] dir] $ 

Python wird (zumindest in einigen Fällen wie in meinem) die Codierung der Shell erben und kann (einige? Alle?) Unicode-Zeichen nicht drucken. Die eigene Standardcodierung von Python, die Sie über sys.getdefaultencoding() und sys.setdefaultencoding() sehen und steuern, wird in diesem Fall ignoriert.

Wenn Sie feststellen, dass Sie dieses Problem haben, können Sie das Problem beheben 

[[email protected] dir] $ export LC_CTYPE="en_EN.UTF-8"
[[email protected] dir] $ locale charmap
UTF-8
[[email protected] dir] $ 

(Oder wählen Sie alternativ die gewünschte Keymap anstelle von en_EN aus.) Sie können auch /etc/locale.conf (oder die Datei, die die Gebietsschemadefinition in Ihrem System regelt) bearbeiten, um dies zu korrigieren.

0
0range