Was ist der Unterschied zwischen Codieren / Decodieren?


180

Ich war mir nie sicher, ob ich den Unterschied zwischen str / unicode decode und encode verstehe.

Ich weiß, dass dies str().decode()der Fall ist, wenn Sie eine Byte-Zeichenfolge haben, von der Sie wissen, dass sie eine bestimmte Zeichencodierung hat. Wenn dieser Codierungsname gegeben ist, wird eine Unicode-Zeichenfolge zurückgegeben.

Ich weiß, dass unicode().encode()Unicode-Zeichen gemäß einem bestimmten Codierungsnamen in eine Zeichenfolge von Bytes konvertiert werden.

Aber ich verstehe nicht wofür str().encode()und bin unicode().decode()dafür. Kann jemand etwas anderes erklären und möglicherweise auch korrigieren, was ich oben falsch verstanden habe?

BEARBEITEN:

Mehrere Antworten geben Auskunft darüber, was .encodeeine Zeichenfolge bewirkt, aber niemand scheint zu wissen, was .decodefür Unicode gilt.


Ich denke, die zweite Antwort auf dieser Seite ist klar und prägnant.
Ben

Antworten:


106

Die decodeMethode der Unicode-Zeichenfolgen hat überhaupt keine Anwendungen (es sei denn, Sie haben aus irgendeinem Grund Nicht-Textdaten in einer Unicode-Zeichenfolge - 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 der sVerwendung des Standardcodecs (ASCII) durch. Überprüfen Sie dies wie folgt:

>>> 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.

Denn str().encode()es umgekehrt ist - es versucht , eine implizite Decodierung des smit der Standard - Codierung:

>>> 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, str().encode()ist auch überflüssig.

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

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

Sie haben jedoch Recht: Die mehrdeutige Verwendung von "Codierung" für diese beiden Anwendungen ist ... unangenehm. Auch hier ist dies mit separaten byteund stringTypen in Python 3 kein Problem mehr.


4
.decode()auf Unicode-Zeichenfolgen könnte nützlich sein, zBprint u'\\u0203'.decode('unicode-escape')
jfs

Gutes Beispiel @JFSebastian in Python3 Ich denke, Sie würden tun:print u'\\u0203'.encode('utf8').decode('unicode-escape')
AJP

1
@ Ajp: auf Python 3:codecs.decode(u'\\u0203', 'unicode-escape')
jfs

@ Hop: Ja. Um ungültige Eingaben zu erkennen und die Python 2/3-Kompatibilität zu gewährleisten, kann die Zeichenfolge explizit mithilfe der folgenden asciiCodierung codiert werden :\\u0203\u00e4'.encode('ascii').decode('unicode-escape')
jfs

@hop: Ihr erster Kommentar (Warum haben Sie ihn gelöscht? Löschen Sie keine Kommentare, auf die geantwortet wurde) hat ihn bereits gesagt. Meine Antwort ( .encode('ascii').decode('unicode-escape')) hängt nicht davon ab sys.getdefaultencoding().
JFS

71

Die Darstellung einer Unicode-Zeichenfolge als Byte-Zeichenfolge wird als Codierung bezeichnet . 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: Der Codec 'ascii' kann keine Zeichen an Position 0-5 codieren: 
    Ordnungszahl nicht im Bereich (128)

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

Das Konvertieren einer Byte-Zeichenfolge in eine Unicode-Zeichenfolge wird als Decodierung bezeichnet . Verwenden Sie unicode('...', encoding)oder '...'. Decodieren (Codieren).

Beispiel:

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

Normalerweise dekodieren Sie eine Zeichenfolge von Bytes, wenn Sie Zeichenfolgendaten vom Netzwerk oder von einer Festplattendatei empfangen.

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

Einige gute Links:


6
Sie haben die Frage des OP nicht beantwortet. OP möchte wissen, was str.encode () und unicode.decode () tun. Sie haben gerade wiederholt, was in der ursprünglichen Frage angegeben wurde.
Stuckintheshuck

Gute Antwort darauf, warum Sie in der Praxis jemals mit Dekodierung und Kodierung herumspielen würden. Nicht jeder Computer versteht den gleichen Zeichensatz, aber alle verstehen Bytes. Codieren Sie in Bytes für eine Sprache, die Computer allgemein verstehen (und die auf die Festplatte übertragen oder gespeichert werden können), aber decodieren Sie, wenn Menschen diese Bytes tatsächlich lesen müssen (z. B. auf der Clientseite).
Alex Petralia

Fantastische Antwort! Das sollte steigen !!
Sandyp

16

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

ein Faden.decode ('encoding') führt zu einem Unicode- Objekt und kann für eine Zeichenfolge aufgerufen werden, die in einer bestimmten Codierung codiert ist.


Noch ein paar Erklärungen:

Sie können ein Unicode-Objekt erstellen, für das keine Codierung festgelegt ist. Die Art und Weise, wie Python es im Speicher speichert, geht Sie nichts an. Sie können es suchen, teilen und jede beliebige Funktion zur Manipulation von Zeichenfolgen aufrufen.

Es kommt jedoch vor, dass Sie Ihr Unicode-Objekt auf der Konsole oder in einer Textdatei drucken möchten. Also musst du codieren (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 - Sie möchten das Gegenteil tun - lesen Sie die in UTF-8 codierte Zeichenfolge und behandeln Sie sie als Unicode, sodass \ u360 ein Zeichen und nicht 5 ist. Dann Sie dekodieren eine Zeichenfolge (mit ausgewählter Codierung) und Holen Sie sich ein brandneues Objekt vom Typ Unicode.

Nur als Randnotiz: Sie können eine perverse Codierung wie 'zip', 'base64', 'rot' auswählen und einige von ihnen werden von String zu String konvertiert, aber ich glaube, der häufigste Fall ist UTF-8 / UTF-16 und String.


12

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

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

Ich bin mir nicht sicher, wozu das Decodieren eines bereits decodierten Unicode-Textes gut ist. Der Versuch, dies mit einer Codierung zu versuchen, scheint immer zuerst zu versuchen, mit der Standardcodierung des Systems zu codieren.


5

Es gibt einige Codierungen, die zum Ent- / Codieren von str zu str oder von Unicode zu Unicode verwendet werden können. Zum Beispiel base64, hex oder sogar rot13. Sie sind im Codecs-Modul aufgeführt .

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. Aber wenn Sie nicht richtig zwischen str und unicode ein- / dekodieren, sieht das sowieso wie ein Durcheinander aus.


1
-1: Die Decodierungsmethode wird nicht auf das Unicode-Objekt angewendet. Stattdessen wird das Unicode-Objekt vor dem Start der Decodierungsoperation als "ASCII" -Bytestring codiert. Um diese Behauptung zu beweisen, versuchen Sie u'ã'.decode ('hex') - das ergibt UnicodeEncodeError
nosklo

2
@nosklo: Du hast recht. Was ich wirklich gemeint habe ist, dass Unicode-Objekte eine decode () -Methode haben, so dass Sie auch Codecs ohne Zeichencodierung auf sie anwenden können. Dieses ganze Geschäft

1

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

Der Computer verwendet die grundlegende Byteeinheit zum Speichern und Verarbeiten von Informationen. es ist für menschliche Augen bedeutungslos.

Zum Beispiel ist '\ xe4 \ xb8 \ xad \ xe6 \ x96 \ x87' die Darstellung von zwei chinesischen Zeichen, aber der Computer weiß nur (dh Drucken oder Speichern), dass es sich um chinesische Zeichen handelt, wenn sie ein Wörterbuch erhalten, um danach zu suchen Chinesisches Wort, in diesem Fall ist es ein "utf-8" -Wörterbuch, und es würde das beabsichtigte chinesische Wort nicht korrekt anzeigen, wenn Sie in ein anderes oder falsches Wörterbuch schauen (unter Verwendung einer anderen Dekodierungsmethode).

In dem obigen Fall ist der Prozess für einen Computer, nach chinesischen Wörtern zu suchen decode().

Und der Prozess des Computerschreibens der Chinesen in den Computerspeicher ist encode().

Die codierten Informationen sind also die Rohbytes, und die decodierten Informationen sind die Rohbytes und der Name des zu referenzierenden Wörterbuchs (jedoch nicht das Wörterbuch selbst).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.