2016-02-26 18 views
5

Ich habe den Punkt über Unicode, Codierung und Decodierung. Aber ich verstehe nicht, warum die encode-Funktion für den str-Typ funktioniert. Ich habe erwartet, dass es nur auf dem Unicode-Typ funktioniert. Daher ist meine Frage: Was ist das Verhalten von codieren, wenn es auf einem Str statt Unicode verwendet wird?Was passiert, wenn encode für str in python verwendet wird?

+0

Was passiert Ihrer Meinung nach mit Unicode, wenn es codiert und decodiert wird? – kojiro

+2

Verwenden Sie Python 3 und die meisten Verwirrung wird weg sein. – Kupiakos

Antwort

5

In Python 2 gibt es zwei Arten von Codecs zur Verfügung stehen; diejenigen, die zwischen str und unicode konvertieren, und solche, die von str zu str konvertieren. Beispiele für letztere sind die Codecs base64 und rot13.

Die str.encode() Methode besteht diese zu unterstützen:

'binary data'.encode('base64') 

Aber jetzt, wo es vorhanden ist, sind die Menschen auch für die unicode mit ->str Codecs; Die Kodierung kann nur von unicode zu str gehen (und umgekehrt dekodieren). Um diese zu unterstützen, Python wird implizit dekodieren Ihren str Wert unicode zuerst, den ASCII-Codec, bevor sie schließlich kodieren.

Nebenbei bemerkt, wenn ein str mit ->str Codec auf einem unicode Objekt, Python codiert zunächst implizit str den gleichen ASCII-Codec.

In Python 3 wird dies durch eine gelöst), um die bytes.encode() und str.decode() Methoden zu entfernen (nicht vergessen, dass bytes ist sorta die alte str und str die neue unicode) und b) durch die str bewegen ->str Kodierungen des codecs Modul nur, die codecs.encode() und codecs.decode() Funktionen.Welche Codecs zwischen den gleichen Typen transformieren, wurde ebenfalls geklärt und aktualisiert, siehe Python Specific Encodings section; Beachten Sie, dass die dort aufgeführten "Text" -Encodierungen, sofern sie in Python 2 verfügbar sind, stattdessen in str codiert werden.

+0

Danke für Ihre Antwort. Außerdem wusste ich nichts über base64 und rot13! – Kowalsy

4

Python erkennt, dass es encode auf einem str Typ nicht tun kann, so versucht es decode es zuerst! Es verwendet den Code 'ascii', der fehlschlägt, wenn Sie Zeichen mit einem Codepoint über 0x7f haben.

Deshalb sehen Sie manchmal einen decode Fehler, der ausgelöst wurde, wenn Sie versuchten, einen encode zu tun.

+0

nitpick: es verwendet 'sys.getdefaultencoding()' (das ist fast immer '' ascii'') – wim

+0

@wim danke dafür, ich wusste es nicht - ich habe 'sys.getdefaultencoding' noch nie etwas anderes gesehen als "Ascii". –

+0

@MarkRansom: Das liegt daran, dass 'sys.setdefaultencoding' durch' site.py' entfernt wurde. 'reload (sys)' wird es zurückbringen, aber den Standard auf etwas anderes als 'ascii' zu setzen ist eine [* sehr schlechte Idee *] (https://stackoverflow.com/questions/28657010/dangers-of-sys-setdefaultencodingutf -8). Du siehst oft 'import sys; neu laden (sys); sys.setdefaultencoding (...) 'cargo-cuted bei Fragen zu Unicode-Problemen. –

3

In Python 3 funktioniert die Codierung eines Byte-Strings einfach nicht. es

>>> b'hi'.encode('utf-8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'bytes' object has no attribute 'encode' 

Python 2 versucht hilfreich sein, wenn Sie encode auf einem str und erste Versuche zu dekodieren die Zeichenfolge mit sys.getdefaultencoding() (in der Regel ascii) und danach kodieren nennen.

Deshalb sollten Sie die die eher seltsame Fehlermeldung erhalten, die mit ascii Decodierung nicht möglich ist, wenn Sie versuchen, mit utf-8 zu kodieren.

>>> 'hi\xFF'.encode('utf-8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 2: ordinal not in range(128) 

Ned erklärt es besser als ich, weiter this von 16.20 beobachten.