Zeichenkodierung in Python verstehen

PythonPythonBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einleitung

In diesem Lab erhalten Sie ein umfassendes Verständnis der Zeichenkodierung in Python. Wir beginnen mit der Geschichte und den grundlegenden Konzepten der Zeichenkodierung, von den Einschränkungen früher Kodierungen wie ASCII und länderspezifischen ANSI-Kodierungen bis hin zur Entwicklung und Bedeutung des Unicode-Standards und seiner verschiedenen Implementierungen wie UTF-8. Sie lernen, wie Sie die Standardkodierung in Ihrer Python-Umgebung überprüfen.

Aufbauend auf diesem Fundament lernen Sie praktische Techniken für die Arbeit mit Zeichenkodierung in Python. Dazu gehört die Verwendung der Funktionen ord() und chr() zur Konvertierung zwischen Zeichen und deren ganzzahligen Darstellungen sowie die Beherrschung der Methoden encode() und decode() zur Konvertierung zwischen Zeichenketten (strings) und Bytes. Schließlich lernen Sie, wie Sie potenzielle Kodierungsfehler, die während des Dekodierungsprozesses auftreten können, effektiv behandeln, um eine robuste und zuverlässige Textverarbeitung in Ihren Python-Anwendungen zu gewährleisten.

Erkundung der Geschichte und Konzepte der Zeichenkodierung

In diesem Schritt werden wir die Geschichte und die grundlegenden Konzepte der Zeichenkodierung untersuchen. Das Verständnis, wie Computer Text darstellen, ist entscheidend für die Arbeit mit verschiedenen Datenformaten und Sprachen.

Anfänglich wurden Computer in den Vereinigten Staaten entwickelt, was zur Erstellung der ASCII-Kodierung führte. ASCII verwendet ein einzelnes Byte zur Darstellung von Zeichen und umfasst englische Buchstaben, Zahlen und Symbole, insgesamt 128 Zeichen.

Als Computer weltweit weiter verbreitet wurden, erwies sich ASCII als unzureichend für die Darstellung von Zeichen aus anderen Sprachen. Dies führte zur Entwicklung verschiedener länderspezifischer Kodierungen wie GB2312, GBK, Big5 und Shift_JIS. Diese wurden oft kollektiv als ANSI-Kodierungen bezeichnet.

Um die Einschränkungen dieser unterschiedlichen Kodierungen zu beheben, wurde der Unicode-Standard entwickelt. Unicode zielt darauf ab, für jedes Zeichen in jeder Sprache einen eindeutigen Binärcode bereitzustellen, was eine konsistente Textverarbeitung über verschiedene Plattformen und Sprachen hinweg ermöglicht. Unicode definiert die Zeichencodes, aber nicht, wie sie gespeichert werden.

Mehrere Kodierungsschemata implementieren Unicode, darunter UCS4, UTF-8, UTF-16 und UTF-32. Unter diesen ist UTF-8 aufgrund seiner Abwärtskompatibilität mit ASCII weit verbreitet.

In Python 3 ist die Standardkodierung UTF-8, die die direkte Verwendung von Zeichen aus verschiedenen Sprachen, einschließlich Akzentzeichen und Symbolen, ermöglicht. In älteren Versionen wie Python 2 mussten Sie die Kodierung normalerweise am Anfang Ihres Skripts mit Kommentaren wie ## -*- coding: UTF-8 -*- oder ## coding=utf-8 angeben.

Sie können die Standardkodierung in Ihrer Python-Umgebung mit dem sys-Modul überprüfen.

Öffnen Sie zuerst das integrierte Terminal in der WebIDE, indem Sie auf Terminal -> New Terminal klicken.

Starten Sie dann den interaktiven Python-Interpreter, indem Sie python eingeben und Enter drücken.

python

Sie sollten eine Ausgabe ähnlich dieser sehen:

Python 3.10.x (main, ...)
[GCC ...] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Importieren Sie nun das sys-Modul und überprüfen Sie die Standardkodierung:

import sys
sys.getdefaultencoding()

Die Ausgabe zeigt die Standardkodierung an, die in Python 3 typischerweise utf-8 ist.

>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>>

Beenden Sie den Python-Interpreter, indem Sie exit() eingeben und Enter drücken.

exit()

Verwenden von ord() und chr() zur Konvertierung von Zeichen und Ganzzahlen

In diesem Schritt lernen wir, wie wir die integrierten Python-Funktionen ord() und chr() verwenden, um zwischen Zeichen und ihren entsprechenden ganzzahligen Darstellungen in Unicode zu konvertieren.

In Python 3 werden Zeichenketten (strings) mithilfe von Unicode dargestellt. Die Funktion ord() nimmt ein einzelnes Zeichen als Eingabe und gibt dessen entsprechenden Unicode-Dezimalganzzahlwert zurück.

Erstellen wir eine neue Python-Datei, um mit diesen Funktionen zu experimentieren. Klicken Sie im WebIDE mit der rechten Maustaste auf das Verzeichnis project im Dateiexplorer und wählen Sie New File. Benennen Sie die Datei char_conversion.py.

Öffnen Sie char_conversion.py im Editor und fügen Sie den folgenden Code hinzu:

## Verwenden von ord(), um den dezimalen Unicode-Wert von Zeichen zu erhalten
char1 = 'a'
char2 = 'é'
char3 = ';'

print(f"Der dezimale Unicode-Wert von '{char1}' ist: {ord(char1)}")
print(f"Der dezimale Unicode-Wert von '{char2}' ist: {ord(char2)}")
print(f"Der dezimale Unicode-Wert von '{char3}' ist: {ord(char3)}")

Speichern Sie die Datei, indem Sie Strg + S (oder Cmd + S unter macOS) drücken.

Öffnen Sie nun erneut das integrierte Terminal (falls es noch nicht geöffnet ist) und führen Sie das Skript mit dem Befehl python aus:

python char_conversion.py

Sie sollten eine Ausgabe ähnlich dieser sehen:

Der dezimale Unicode-Wert von 'a' ist: 97
Der dezimale Unicode-Wert von 'é' ist: 233
Der dezimale Unicode-Wert von ';' ist: 59

Die Funktion chr() führt die umgekehrte Operation durch. Sie nimmt eine Dezimalganzzahl (oder eine Hexadezimalganzzahl) entgegen, die einen Unicode-Codepunkt darstellt, und gibt das entsprechende Zeichen zurück.

Fügen wir char_conversion.py weiteren Code hinzu, um die Funktion chr() zu verwenden. Hängen Sie die folgenden Zeilen an den vorhandenen Code an:

## Verwenden von chr(), um das Zeichen aus einem dezimalen Unicode-Wert zu erhalten
int1 = 8364
int2 = 8482

print(f"Das Zeichen für den dezimalen Unicode-Wert {int1} ist: {chr(int1)}")
print(f"Das Zeichen für den dezimalen Unicode-Wert {int2} ist: {chr(int2)}")

## Sie können auch Hexadezimalwerte mit chr() verwenden
hex_int = 0x00A9 ## Hexadezimal für das Zeichen '©'
print(f"Das Zeichen für den hexadezimalen Unicode-Wert {hex(hex_int)} ist: {chr(hex_int)}")

Speichern Sie die Datei erneut.

Führen Sie das Skript vom Terminal aus:

python char_conversion.py

Die Ausgabe sollte nun die Ergebnisse der chr()-Funktion enthalten:

Der dezimale Unicode-Wert von 'a' ist: 97
Der dezimale Unicode-Wert von 'é' ist: 233
Der dezimale Unicode-Wert von ';' ist: 59
Das Zeichen für den dezimalen Unicode-Wert 8364 ist: €
Das Zeichen für den dezimalen Unicode-Wert 8482 ist: ™
Das Zeichen für den hexadezimalen Unicode-Wert 0xa9 ist: ©

Sie fragen sich vielleicht, wie Sie die hexadezimale Unicode-Darstellung eines Zeichens finden können. Sie können die Funktion ord() verwenden, um den Dezimalwert zu erhalten, und dann die integrierte Funktion hex(), um den Dezimalwert in seine hexadezimale Zeichenkettenrepräsentation zu konvertieren.

Fügen Sie den folgenden Code zu char_conversion.py hinzu:

## Konvertieren eines Zeichens in seine hexadezimale Unicode-Darstellung
char_copyright = '©'
decimal_copyright = ord(char_copyright)
hexadecimal_copyright = hex(decimal_copyright)

print(f"Der hexadezimale Unicode-Wert von '{char_copyright}' ist: {hexadecimal_copyright}")

Speichern Sie die Datei und führen Sie sie ein letztes Mal aus:

python char_conversion.py

Die endgültige Ausgabe enthält den hexadezimalen Wert für das Zeichen '©':

Der dezimale Unicode-Wert von 'a' ist: 97
Der dezimale Unicode-Wert von 'é' ist: 233
Der dezimale Unicode-Wert von ';' ist: 59
Das Zeichen für den dezimalen Unicode-Wert 8364 ist: €
Das Zeichen für den dezimalen Unicode-Wert 8482 ist: ™
Das Zeichen für den hexadezimalen Unicode-Wert 0xa9 ist: ©
Der hexadezimale Unicode-Wert von '©' ist: 0xa9

Dies zeigt, wie ord(), chr() und hex() zusammen verwendet werden können, um mit Zeichenkodierungen in Python zu arbeiten.

Konvertierung zwischen Zeichenketten und Bytes mit encode() und decode()

In diesem Schritt lernen wir, wie wir mit den Methoden encode() und decode() zwischen Python-Zeichenketten (die Unicode sind) und Bytes-Objekten konvertieren. Dies ist unerlässlich, wenn mit Daten gearbeitet wird, die in einem bestimmten Kodierungsformat übertragen oder gespeichert werden müssen.

Die Methode encode() wird verwendet, um eine Zeichenkette mithilfe einer angegebenen Kodierung in ein Bytes-Objekt zu konvertieren. Sie gibt ein bytes-Objekt zurück.

Erstellen wir eine neue Python-Datei namens encoding_decoding.py im Verzeichnis ~/project.

Öffnen Sie encoding_decoding.py im Editor und fügen Sie den folgenden Code hinzu:

## Definieren einer Zeichenkette
my_string = 'café'

## Kodieren der Zeichenkette mit UTF-8
encoded_utf8 = my_string.encode('utf-8')

## Kodieren der Zeichenkette mit Latin-1
encoded_latin1 = my_string.encode('latin-1')

## Ausgeben der kodierten Bytes-Objekte
print(f"Originale Zeichenkette: {my_string}")
print(f"Kodiert in UTF-8: {encoded_utf8}")
print(f"Kodiert in Latin-1: {encoded_latin1}")

Speichern Sie die Datei.

Führen Sie nun das Skript im integrierten Terminal aus:

python encoding_decoding.py

Sie sollten eine Ausgabe sehen, die die ursprüngliche Zeichenkette und ihre Byte-Darstellung sowohl in UTF-8 als auch in Latin-1 zeigt:

Originale Zeichenkette: café
Kodiert in UTF-8: b'caf\xc3\xa9'
Kodiert in Latin-1: b'caf\xe9'

Beachten Sie, dass die Ausgabe für die Bytes-Objekte mit b' beginnt, was anzeigt, dass es sich um Byte-Literale handelt. Die Hexadezimalzahlen stellen die Byte-Sequenzen für die Zeichenkette in jeder Kodierung dar.

Die Methode decode() wird verwendet, um ein Bytes-Objekt mithilfe einer angegebenen Kodierung wieder in eine Zeichenkette zu konvertieren.

Fügen wir encoding_decoding.py Code hinzu, um die von uns erstellten Bytes-Objekte zu dekodieren. Hängen Sie die folgenden Zeilen an den vorhandenen Code an:

## Dekodieren der Bytes-Objekte zurück in Zeichenketten
decoded_utf8 = encoded_utf8.decode('utf-8')
decoded_latin1 = encoded_latin1.decode('latin-1')

## Ausgeben der dekodierten Zeichenketten
print(f"Dekodiert von UTF-8: {decoded_utf8}")
print(f"Dekodiert von Latin-1: {decoded_latin1}")

Speichern Sie die Datei.

Führen Sie das Skript erneut aus:

python encoding_decoding.py

Die Ausgabe zeigt nun die ursprüngliche Zeichenkette, die erfolgreich sowohl aus UTF-8- als auch aus Latin-1-Bytes dekodiert wurde:

Originale Zeichenkette: café
Kodiert in UTF-8: b'caf\xc3\xa9'
Kodiert in Latin-1: b'caf\xe9'
Dekodiert von UTF-8: café
Dekodiert von Latin-1: café

Dies demonstriert den grundlegenden Prozess der Kodierung einer Zeichenkette in Bytes und der Dekodierung von Bytes zurück in eine Zeichenkette unter Verwendung spezifischer Kodierungen. Es ist entscheidend, die richtige Kodierung sowohl für die Kodierung als auch für die Dekodierung zu verwenden, um Fehler zu vermeiden, die wir im nächsten Schritt untersuchen werden.

Behandlung von Kodierungsfehlern beim Dekodieren

In diesem Schritt untersuchen wir, was passiert, wenn Sie versuchen, Bytes mit der falschen Kodierung zu dekodieren, und wie Sie solche Fehler behandeln können.

Wie wir im vorherigen Schritt gesehen haben, ist für die erfolgreiche Dekodierung von Bytes die Kenntnis der ursprünglichen Kodierung, die zum Erstellen dieser Bytes verwendet wurde, erforderlich. Wenn Sie versuchen, Bytes mit einer inkompatiblen Kodierung zu dekodieren, löst Python einen Fehler aus.

Modifizieren wir unsere Datei encoding_decoding.py, um dies zu demonstrieren. Öffnen Sie die Datei im Editor und fügen Sie den folgenden Code am Ende hinzu:

## Versuch, Latin-1-kodierte Bytes mit ASCII zu dekodieren
try:
    decoded_incorrectly = encoded_latin1.decode('ascii')
    print(f"Dekodiert von Latin-1 mit ASCII: {decoded_incorrectly}")
except UnicodeDecodeError as e:
    print(f"Fehler beim Dekodieren von Latin-1 mit ASCII: {e}")

Speichern Sie die Datei.

Führen Sie das Skript vom Terminal aus:

python encoding_decoding.py

Die Ausgabe enthält nun die Fehlermeldung beim Versuch, Latin-1-Bytes mit ASCII zu dekodieren:

Originale Zeichenkette: café
Kodiert in UTF-8: b'caf\xc3\xa9'
Kodiert in Latin-1: b'caf\xe9'
Dekodiert von UTF-8: café
Dekodiert von Latin-1: café
Fehler beim Dekodieren von Latin-1 mit ASCII: 'ascii' codec can't decode byte 0xe9 in position 3: ordinal not in range(128)

Der UnicodeDecodeError zeigt an, dass der ASCII-Codec auf Bytes gestoßen ist, die gemäß dem ASCII-Standard nicht gültig sind. In diesem Fall ist das Byte 0xe9 die Latin-1-Darstellung von 'é', aber es ist kein gültiges ASCII-Zeichen (ASCII deckt nur Zeichen von 0-127 ab).

Beim Dekodieren können Sie auch festlegen, wie Fehler mithilfe des Parameters errors der Methode decode() behandelt werden sollen. Gängige Strategien zur Fehlerbehandlung sind:

  • 'strict' (Standard): Löst einen UnicodeDecodeError aus.
  • 'ignore': Ignoriert die nicht dekodierbaren Bytes.
  • 'replace': Ersetzt die nicht dekodierbaren Bytes durch ein Ersatzzeichen (normalerweise ``).
  • 'xmlcharrefreplace': Ersetzt die nicht dekodierbaren Bytes durch XML-Zeichenreferenzen.

Fügen wir Beispiele für die Verwendung der Fehlerbehandlungsstrategien 'ignore' und 'replace' zu encoding_decoding.py hinzu. Hängen Sie den folgenden Code an:

## Versuch, Latin-1-kodierte Bytes mit ASCII und Fehlerbehandlung zu dekodieren
decoded_ignore = encoded_latin1.decode('ascii', errors='ignore')
decoded_replace = encoded_latin1.decode('ascii', errors='replace')

print(f"Dekodiert von Latin-1 mit ASCII (Fehler ignorieren): {decoded_ignore}")
print(f"Dekodiert von Latin-1 mit ASCII (Fehler ersetzen): {decoded_replace}")

Speichern Sie die Datei.

Führen Sie das Skript erneut aus:

python encoding_decoding.py

Die Ausgabe zeigt nun die Ergebnisse mit Fehlerbehandlung:

Originale Zeichenkette: café
Kodiert in UTF-8: b'caf\xc3\xa9'
Kodiert in Latin-1: b'caf\xe9'
Dekodiert von UTF-8: café
Dekodiert von Latin-1: café
Fehler beim Dekodieren von Latin-1 mit ASCII: 'ascii' codec can't decode byte 0xe9 in position 3: ordinal not in range(128)
Dekodiert von Latin-1 mit ASCII (Fehler ignorieren): caf
Dekodiert von Latin-1 mit ASCII (Fehler ersetzen): caf

Wie Sie sehen können, führt 'ignore' zu "caf", da das ungültige Byte ignoriert wurde und das Zeichen 'é' entfernt wurde. 'replace' ersetzt das ungültige Byte durch das Ersatzzeichen ``, was zu "caf" führt.

Die Wahl der geeigneten Fehlerbehandlungsstrategie hängt von Ihren spezifischen Anforderungen ab. In den meisten Fällen ist es am besten, während der Entwicklung 'strict' zu verwenden, um Kodierungsprobleme frühzeitig zu erkennen. In der Produktion können Sie 'replace' oder 'ignore' wählen, wenn Sie Daten mit potenziellen Kodierungsproblemen verarbeiten müssen, aber seien Sie sich bewusst, dass dies zu Datenverlust oder -beschädigung führen kann.

Zusammenfassung

In diesem Lab haben wir die Geschichte und die grundlegenden Konzepte der Zeichenkodierung untersucht, beginnend mit ASCII und seinen Einschränkungen, die zur Entwicklung verschiedener länderspezifischer Kodierungen und schließlich zum Unicode-Standard führten. Wir haben gelernt, dass Unicode jedem Zeichen einen eindeutigen Code zuweist und durch verschiedene Kodierungsschemata wie UTF-8 implementiert wird, das in Python 3 der Standard ist und abwärtskompatibel mit ASCII ist. Wir haben auch gelernt, wie die Standardkodierung in Python mithilfe des sys-Moduls überprüft werden kann.

Anschließend haben wir die Konvertierung zwischen Zeichen und ihren ganzzahligen Darstellungen mithilfe der Funktionen ord() und chr() sowie zwischen Zeichenketten und Bytes mithilfe der Methoden encode() und decode() geübt. Schließlich haben wir uns damit befasst, wie potenzielle Kodierungsfehler, die während des Dekodierungsprozesses auftreten können, behandelt werden.