Unicode und Zeichenkodierungen¶
Es gibt Dutzende von Zeichenkodierungen. Einen Überblick über die Encodings von Python erhaltet ihr in Encodings and Unicode.
Das string-Modul¶
Das string-Modul von Python unterscheidet die folgenden String-Konstanten, die alle in den ASCII-Zeichensatz fallen:
# Some strings for ctype-style character classification
whitespace = " \t\n\r\v\f"
ascii_lowercase = "abcdefghijklmnopqrstuvwxyz"
ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
ascii_letters = ascii_lowercase + ascii_uppercase
digits = "0123456789"
hexdigits = digits + "abcdef" + "ABCDEF"
octdigits = "01234567"
punctuation = r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
printable = digits + ascii_letters + punctuation + whitespace
Die meisten dieser Konstanten sollten in ihrem Bezeichnernamen selbsterklärend
sein. hexdigits und octdigits beziehen sich auf die
Hexadezimal- bzw. Oktalwerte. Ihr könnt diese
Konstanten für alltägliche String-Manipulation verwenden:
>>> import string
>>> hepy = "Hello Pythonistas!"
>>> hepy.rstrip(string.punctuation)
'Hello Pythonistas'
Das string-Modul arbeitet jedoch standardmäßig mit Unicode, der als Binärdaten (Bytes) dargestellt wird.
Unicode¶
Es ist offensichtlich, dass der ASCII-Zeichensatz nicht annähernd groß genug ist, um alle Sprachen, Dialekte, Symbole und Glyphen zu erfassen; er ist nicht einmal groß genug für das Englische.
ASCII ist zwar eine vollständige Untermenge von Unicode – die ersten 128 Zeichen in der Unicode-Tabelle entsprechen genau den ASCII-Zeichen – Unicode umfasst jedoch eine viel größere Menge von Zeichen. Dabei ist Unicode selbst keine Kodierung sondern wird durch verschiedene Zeichenkodierungen implementiert wobei UTF-8 das vermutlich am häufigsten verwendete Kodierungsschema ist.
Bemerkung
Die Python-Hilfedokumentation hat einen Eintrag für Unicode: gebt help()
und dann UNICODE ein. Es wird ausführlich auf die verschiedenen
Möglichkeiten, Python-Strings zu erstellen, eingegangen.
Unicode und UTF-8¶
Während Unicode ein abstrakter Kodierungsstandard ist, ist UTF-8 ein konkretes Kodierungsschema. Der Unicode-Standard ist eine Zuordnung von Zeichen zu Codepunkten und definiert mehrere verschiedene Kodierungen aus einem einzigen Zeichensatz. UTF-8 ist ein Kodierungsschema für die Darstellung von Unicode-Zeichen als Binärdaten mit einem oder mehreren Bytes pro Zeichen.
Kodierung und Dekodierung in Python 3¶
Der str-Typ ist für die Darstellung von
menschenlesbarem Text gedacht und kann alle Unicode-Zeichen enthalten. Der
bytes-Typ hingegen repräsentiert Binärdaten, die
nicht von vornherein mit einer Kodierung versehen sind.
str.encode() und bytes.decode() sind die Methoden
des Übergangs vom einen zum anderen:
>>> "schön".encode("utf-8")
b'sch\xc3\xb6n'
>>> b"sch\xc3\xb6n".decode("utf-8")
'schön'
Das Ergebnis von str.encode() ist ein Bytes-Objekt. Sowohl Bytes-Literale (wie b'sch\xc3\xb6n') als auch
die Darstellungen von Bytes lassen nur ASCII-Zeichen zu. Aus diesem Grund darf
beim Aufruf von "schön".encode("utf-8") das ASCII-kompatible "sch" so
dargestellt werden, wie es ist, das ö
wird jedoch zu "\xc3\xb6". Diese chaotisch aussehende Sequenz repräsentiert
zwei Bytes, c3 und b6 als Hexadezimalwerte.
Tipp
In .encode() und .decode() ist der Kodierungsparameter standardmäßig
"utf-8"; dennoch empfiehlt sich, ihn explizit anzugeben.
Mit bytes.fromhex() könnt ihr die Hexadezimalwerte in Bytes
umwandeln:
>>> bytes.fromhex("c3 b6")
b'\xc3\xb6'
UTF-16 und UTF-32¶
Der Unterschied zwischen diesen und UTF-8 ist in der Praxis erheblich. Im Folgenden möchte ich euch nur kurz an einem Beispiel zeigen, dass hier eine eine Round-Trip-Konvertierung einfach fehlschlagen kann:
>>> hepy = "Hello Pythonistas!"
>>> hepy.encode("utf-8")
b'Hello Pythonistas!'
>>> len(hepy.encode("utf-8"))
18
>>> hepy.encode("utf-8").decode("utf-16")
'效汬\u206f祐桴湯獩慴ⅳ'
>>> len(hepy.encode("utf-8").decode("utf-16"))
9
Die Kodierung von lateinischen Buchstaben in UTF-8 und die anschließende Dekodierung in UTF-16 führte zu einem Text, der auch Zeichen aus dem chinesischen, japanischen oder koreanischen Sprachraum sowie römische Ziffern enthält. Die Dekodierung desselben Byte-Objekts kann zu Ergebnissen führen, die nicht einmal in derselben Sprache sind oder gleich viele Zeichen enthalten.
Python 3 und Unicode¶
Python 3 setzt voll und ganz auf Unicode und speziell auf UTF-8:
Der Quellcode von Python 3 wird standardmäßig in UTF-8 angenommen.
Texte (str) sind standardmäßig Unicode. Kodierter Unicode-Text wird als Binärdaten (Bytes) dargestellt.
Python 3 akzeptiert viele Unicode-Codepunkte in Bezeichnern.
Pythons re-Modul verwendet standardmäßig das
re.UNICODE-Flag und nichtre.ASCII. Das bedeutet, dass z.B.r"\w"auf Unicode-Wortzeichen passt, nicht nur auf ASCII-Buchstaben.Die Standardkodierung in
str.encode()undbytes.decode()ist UTF-8.
Die einzige Ausnahme könnte open() sein, das
plattformabhängig ist und daher vom Wert von
locale.getpreferredencoding() abhängt:
>>> import locale
>>> locale.getpreferredencoding()
'UTF-8'
Built-In Python-Funktionen¶
Python verfügt über eine Reihe von eingebauten Funktionen, die sich in irgendeiner Weise auf Zeichenkodierungen beziehen:
ascii(),bin(),hex(),oct()geben einen String aus.
bytes,str,intsind Klassenkonstruktoren für ihre jeweiligen Typen, die die Eingabe in den gewünschten Typ konvertiert.
ord(),chr()sind insofern invers zueinander, als die Python-Funktion
ord()einstr-Zeichen in seinenbase=10-Codepunkt umwandelt, währendchr()das Gegenteil tut.
Im Folgenden findet ihr einen detaillierteren Blick auf jede dieser neun Funktionen:
Funktion |
Rückgabetyp |
Beschreibung |
|---|---|---|
|
ASCII-Darstellung eines Objekts, wobei nicht-ASCII-Zeichen escaped werden |
|
|
binäre Darstellung einer ganzen Zahl
mit dem Präfix |
|
|
hexadezimale Darstellung einer ganzen
Zahl mit dem Präfix |
|
|
Oktaldarstellung einer ganzen Zahl
mit dem Präfix |
|
|
konvertiert die Eingabe in bytes-Typ |
|
|
konvertiert die Eingabe in str-Typ |
|
|
konvertiert die Eingabe in
|
|
|
konvertiert ein einzelnes Unicode-Zeichen in seinen Integer-Codepunkt |
|
|
wandelt einen Integer-Codepunkt in ein einzelnes Unicode-Zeichen um |