web-dev-qa-db-de.com

Was ist der Unterschied zwischen Kodierung/Dekodierung?

Ich war nie sicher, dass ich den Unterschied zwischen str/Unicode-Dekodierung und Kodierung verstehe.

Ich weiß, dass str().decode() ist, wenn Sie über eine Byte-Zeichenkette verfügen, von der Sie wissen, dass sie eine bestimmte Zeichenkodierung hat. Wenn Sie diesen Kodierungsnamen angeben, wird eine Unicode-Zeichenfolge zurückgegeben.

Ich weiß, dass unicode().encode() Unicode-Zeichen entsprechend einem gegebenen Codierungsnamen in eine Folge von Bytes konvertiert.

Aber ich verstehe nicht, wofür str().encode() und unicode().decode() sind. Kann jemand erklären und möglicherweise auch alles korrigieren, was ich oben falsch gemacht habe?

BEARBEITEN:

Mehrere Antworten geben Auskunft darüber, was .encode an einer Zeichenfolge bewirkt, aber niemand scheint zu wissen, was .decode für Unicode tut.

169
ʞɔıu

Die decode-Methode von Unicode-Strings hat wirklich keine Anwendungen (es sei denn, Sie haben aus einem bestimmten Grund Nicht-Text-Daten in einem Unicode-String - siehe unten). Es ist hauptsächlich aus historischen Gründen da, denke ich. In Python 3 ist es komplett weg.

unicode().decode() führt eine implizite Codierung von s mit dem Standardcodec (ascii) durch. Überprüfen Sie das so:

>>> s = u'ö'
>>> s.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

>>> s.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

Die Fehlermeldungen sind genau gleich.

Für str().encode() ist es umgekehrt: Es versucht eine implizite decodierung von s mit der Standardcodierung:

>>> s = 'ö'
>>> s.decode('utf-8')
u'\xf6'
>>> s.encode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)

So verwendet ist str().encode() auch überflüssig.

Aber Es gibt eine andere Anwendung der letzteren Methode, die nützlich ist: Es gibt encodings , die nichts mit Zeichensätzen zu tun haben, und können daher auf 8-Bit-Strings auf sinnvolle Weise angewendet werden:

>>> s.encode('Zip')
'x\x9c;\xbc\r\x00\x02>\x01z'

Sie haben jedoch recht: Die mehrdeutige Verwendung von "Encoding" für diese beiden Anwendungen ist ... awkard. Mit den unterschiedlichen byte- und string-Typen in Python 3 ist dies kein Problem mehr.

99
user3850

Um eine Unicode-Zeichenfolge als Byte-Zeichenfolge darzustellen, wird als bezeichnet codierung. Verwenden Sie u'...'.encode(encoding).

Beispiel:

 >>> u'æøå'encode ('utf8') 
 '\ xc3\x83\xc2\xa6\xc3\x83\xc2\xb8\xc3\x83\xc2\xa5' 
 >>> u'æøå'encode ('latin1') 
 '\ xc3\xa6\xc3\xb8\xc3\xa5' 
 >>> u'æøå'encode ('ascii') 
 UnicodeEncodeError: Codec 'ascii' kann Zeichen an Position 0-5: .__ nicht codieren. Ordinalzahl nicht im Bereich (128) 

Normalerweise kodieren Sie eine Unicode-Zeichenfolge, wenn Sie sie für E/A verwenden müssen, beispielsweise über das Netzwerk übertragen oder in einer Festplattendatei speichern.

Eine Zeichenfolge von Bytes in eine Unicode-Zeichenfolge umzuwandeln ist bekannt als dekodierung. Verwenden Sie unicode('...', encoding) oder '...'. Decodieren (kodieren).

Beispiel:

 >>> u'æøå '
 u '\ xc3\xa6\xc3\xb8\xc3\xa5' # Der Interpreter gibt das Unicode-Objekt wie folgt aus 
 >>> Unicode ('\ xc3\xa6\xc3\xb8\xc3\xa5', 'latin1') 
 u '\ xc3\xa6\xc3\xb8\xc3\xa5' 
 >>> '\ xc3\xa6\xc3\xb8\xc3\xa5' .code ('latin1') 
 u '\ xc3\xa6\xc3\xb8\xc3\xa5' 

Sie dekodieren normalerweise eine Bytefolge, wenn Sie Zeichenfolgendaten vom Netzwerk oder von einer Datenträgerdatei erhalten.

Ich glaube, es gibt einige Änderungen in der Unicode-Handhabung in Python 3, daher ist das Obige für Python 3 wahrscheinlich nicht korrekt.

Einige gute Links:

68
codeape

anUnicode .encode ('encoding') führt zu einem string - Objekt und kann für ein Unicode-Objekt aufgerufen werden 

aString .decode ('encoding') führt zu einem unicode - Objekt und kann für einen String aufgerufen werden, der in der angegebenen Codierung codiert ist.


Einige weitere Erklärungen:

Sie können ein Unicode-Objekt erstellen, für das kein Kodierungssatz festgelegt ist. Die Art und Weise, wie Python im Speicher abgelegt wird, ist nicht von Belang. Sie können es durchsuchen, teilen und eine beliebige Zeichenfolgenbearbeitungsfunktion aufrufen.

Es gibt jedoch eine Zeit, in der Sie Ihr Unicode-Objekt auf die Konsole oder in eine Textdatei drucken möchten. Sie müssen also encode it (zum Beispiel - in UTF-8), Sie rufen encode ('utf-8') auf und Sie erhalten eine Zeichenfolge mit '\ u <someNumber>', die perfekt druckbar ist.

Dann, wieder - möchten Sie das Gegenteil tun - lesen Sie den in UTF-8 codierten String und behandeln ihn als Unicode, sodass das Zeichen\360 ein Zeichen und nicht 5 ist. Dann decode einen String (mit ausgewählte Kodierung) und erhalten ein brandneues Objekt des Unicode-Typs.

Nur als Randnotiz - Sie können einige Perverscodierungen auswählen, wie 'Zip', 'base64', 'rot' und einige von ihnen konvertieren von String zu String, aber ich glaube, der häufigste Fall ist UTF-8/UTF-16 und Zeichenfolge.

15
Abgan

mybytestring.encode (somecodec) ist für diese Werte von somecodec von Bedeutung:

  • base64 
  • bz2
  • zlib
  • hex
  • quopri
  • rot13
  • string_escape
  • uu

Ich bin nicht sicher, wofür die Dekodierung eines bereits dekodierten Unicode-Textes gut ist. Wenn Sie dies mit einer beliebigen Codierung versuchen, scheint es immer zuerst zu versuchen, mit der Standardcodierung des Systems zu codieren.

12
nosklo

Sie sollten Python UnicodeDecodeError lesen - Bin ich falsch codiert . Mein Verständnis von Unicode in Python war viel klarer, nachdem ich die akzeptierte Antwort gelesen hatte.

8
Oli

Es gibt einige Kodierungen, die zur Dekodierung von str nach str oder von Unicode zu Unicode verwendet werden können. Zum Beispiel base64, hex oder sogar rot13. Sie sind im codecs-Modul aufgelistet.

Bearbeiten:

Die Decodierungsnachricht in einer Unicode-Zeichenfolge kann die entsprechende Codierungsoperation rückgängig machen:

In [1]: u'0a'.decode('hex')
Out[1]: '\n'

Der zurückgegebene Typ ist str anstelle von Unicode, was meiner Meinung nach unglücklich ist. Wenn Sie jedoch keine korrekte Dekodierung zwischen str und unicode durchführen, sieht das sowieso aus wie ein Chaos.

5
unbeknown

Die einfache Antwort ist, dass sie genau das Gegenteil sind.

der Computer verwendet die grundlegende Einheit von Byte zum Speichern und Verarbeiten von Informationen und ist für das menschliche Auge ohne Bedeutung.

zum Beispiel ist '\ xe4\xb8\xad\xe6\x96\x87' die Darstellung von zwei chinesischen Schriftzeichen, aber der Computer weiß nur (dh Drucken oder Speichern), dass es chinesische Zeichen sind, wenn ihnen ein Wörterbuch zur Verfügung gestellt wird Chinesisches Wort, in diesem Fall handelt es sich um ein "utf-8" -Wörterbuch, und das beabsichtigte chinesische Wort wird möglicherweise nicht korrekt angezeigt, wenn Sie in ein anderes oder falsches Wörterbuch schauen (mit einer anderen Dekodierungsmethode). 

In diesem Fall ist der Vorgang, mit dem ein Computer nach chinesischem Wort sucht, decodiert (). 

Und der Computer, der die Chinesen in den Computerspeicher schreibt, ist encode ().

die Kodierungsinformationen sind also die rohen Bytes, und die dekodierten Informationen sind die rohen Bytes und der Name des zu referenzierenden Wörterbuchs (nicht das Wörterbuch selbst).

0
Eren Bay