HOWTO · Python
str object has no attribute decode behoben in Python
In diesem Tutorial wird der str has no attribute decode error in Python besprochen.
Auf dieser Seite
Wenn Python AttributeError: 'str' object has no attribute 'decode' meldet, ist der Wert, auf den decode() angewendet wird, Text und keine Bytefolge. Entfernen Sie den Aufruf in Python 3, wenn der Wert bereits ein str ist. Verwenden Sie decode() nur für bytes, die Sie in Text umwandeln müssen, und nehmen Sie diese Umwandlung an der Stelle vor, an der die Bytes in Ihr Programm gelangen.
Den Fehler 'str' object has no attribute 'decode' verstehen
Python 3 behandelt Text und Bytefolgen als unterschiedliche Typen. Ein str enthält Unicode-Text; ein Wert vom Typ bytes enthält rohe Bytewerte, die codierten Text darstellen können. Die Methode decode() gehört zu Bytes, denn beim Dekodieren werden die Bytes mithilfe einer Zeichenkodierung interpretiert und in einen str umgewandelt. Ein Python-3-String ist kein codierter Bytewert, der noch dekodiert werden muss.
Der Fehler tritt auf, wenn der Code decode() auf einen Wert vom Typ str anwendet. Der Ausdruck "Hello".decode("utf-8") versucht beispielsweise, eine Bytes-Operation auf Text anzuwenden. Python meldet den betreffenden AttributeError, weil str keine Methode decode hat. Das kommt häufig vor, wenn älterer Python-2-Code nach Python 3 übertragen wird oder eine Bibliothek die Daten bereits dekodiert zurückgibt.
Führen Sie dieses Minimalbeispiel aus, um die Fehlermeldung als auswählbaren Text zu erhalten:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
try:
"Hello".decode("utf-8")
except AttributeError as error:
print(f"{type(error).__name__}: {error}")
AttributeError: 'str' object has no attribute 'decode'
Entscheidend ist daher nicht, welche Kodierung Sie an decode() übergeben, sondern welchen Typ der aktuelle Wert hat und woher er stammt. Ist es Text, verwenden Sie ihn weiter als Text. Ist es ein Bytewert, dekodieren Sie ihn einmal mit der von der Quelle angegebenen Kodierung. Fügen Sie keine Umwandlung nur hinzu, um die Fehlermeldung zum Verschwinden zu bringen.
Die passende Korrektur für Text oder Bytes wählen
Ist der Wert bereits Text, entfernen Sie den Aufruf von .decode(...) und verwenden Sie den String direkt. Das ist die übliche Korrektur für den genannten Fehler. Liefert Ihnen beispielsweise ein Antwortparser, ein Datenbanktreiber oder das Lesen einer Datei im Textmodus einen str, geben Sie diesen Wert ohne erneutes Dekodieren an die nächste Funktion weiter.
Führen Sie dieses Beispiel aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
message = "Hello, Python!"
print(message)
Hello, Python!
Die entscheidende Korrektur besteht darin, den String direkt an print zu übergeben; eine Umwandlungskette aus Codieren und anschließendem Dekodieren ist nicht erforderlich. Nehmen Sie dieselbe Änderung an der fehlerhaften Zeile vor: Entfernen Sie den Aufruf selbst, statt ihn durch eine andere Umwandlung zu ersetzen.
encode() führt die umgekehrte Umwandlung aus: Die Methode wandelt Text mit einer ausgewählten Kodierung in Bytes um. Verwenden Sie sie, wenn eine API, ein Dateiformat oder ein Protokoll ausdrücklich Bytes verlangt. Einen String zu codieren und diese Bytes sofort wieder in den ursprünglichen Text zurückzudekodieren, ist überflüssig, wenn dazwischen keine Operation mit Bytes stattfindet. Das behebt einen Typkonflikt nicht sinnvoll und kann verschleiern, an welcher Stelle Text in Bytes umgewandelt wird.
Wählen Sie die Operation passend zum Typ und zum nächsten benötigten Verarbeitungsschritt: Behalten Sie str für die Textverarbeitung bei, verwenden Sie encode(), wenn Bytes benötigt werden, und decode(), wenn Bytes zu Text werden sollen. Diese Richtung ist wichtig, denn Kodierungen legen fest, wie Zeichen Bytes zugeordnet werden. Sie sind keine Aufforderung, jeden String zu kodieren.
Bytes an der Datengrenze dekodieren
Wenn die Prüfung ergibt, dass die Eingabe ein Objekt vom Typ bytes ist, ist Dekodieren angebracht. Dekodieren Sie den Wert einmal, sobald er in den Teil Ihres Programms gelangt, der Text verarbeitet, und verwenden Sie dabei die von der Quelle dokumentierte Kodierung. UTF-8 ist verbreitet; welche Kodierung richtig ist, hängt jedoch von der Datei, dem Dienst oder dem Protokoll ab, das die Bytes geliefert hat.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
raw_data = b"caf\xc3\xa9"
text = raw_data.decode("utf-8")
print(repr(text))
Hier enthält raw_data die UTF-8-Bytes für café. Daher wandelt decode("utf-8") diese Bytes in einen String um. Das Nicht-ASCII-Zeichen macht die Kodierungsgrenze sichtbar: In UTF-8 wird es durch mehr als ein Byte dargestellt, im resultierenden Text ist es jedoch ein einzelnes Zeichen. Wenn Python den Inhalt beim Lesen dekodieren soll, öffnen Sie eine Datei im Textmodus mit der richtigen Kodierung. Lesen Sie Binärdaten oder erhalten Sie Bytes von einem Socket oder einer Bibliothek, dekodieren Sie den Bytewert an dieser Eingabegrenze, bevor Sie ihn an textverarbeitenden Code übergeben.
Auch eine leere Bytefolge ist eine gültige Eingabe. Dieses Beispiel wandelt sie an der Eingabegrenze um, ohne „kein Inhalt“ als Dekodierungsfehler zu behandeln:
raw_data = b""
text = raw_data.decode("utf-8")
print(repr(text))
''
Behandeln Sie den resultierenden leeren String entsprechend der Bedeutung, die „kein Inhalt“ in Ihrer Anwendung hat. Bytes, die in der angegebenen Kodierung ungültig sind, erfordern hingegen eine festgelegte Strategie, etwa einen Dekodierungsfehler zu melden oder eine dokumentierte Ersetzungsstrategie anzuwenden. Wählen Sie nicht stillschweigend eine andere Kodierung, nur damit das Dekodieren gelingt.
Vermeiden Sie es, denselben Inhalt bei jedem Funktionsaufruf erneut zu dekodieren. Sobald die Daten zu einem str geworden sind, sollten nachgelagerte Funktionen Text entgegennehmen und nicht nochmals decode() aufrufen. Benötigt eine nachgelagerte API Bytes, codieren Sie den Wert stattdessen an dieser API-Grenze. Klar festgelegte Umwandlungsgrenzen erleichtern es zu erkennen, welche Ebene für die Entscheidung über die Kodierung zuständig ist.
Die Quelle des Strings zurückverfolgen und korrigieren
Um den fehlerhaften Wert zu finden, suchen Sie die im Traceback genannte Zeile und prüfen Sie das Objekt direkt vor .decode(). Ermitteln Sie den Typ mit type(value) oder isinstance(value, bytes). Bei einem verschachtelten Verarbeitungsweg kann eine kurze Diagnose helfen:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
value = "already text"
print(type(value).__name__)
Meldet die Prüfung str, entfernen Sie den Aufruf von decode und verfolgen Sie den Wert bis zu der Funktion, Datei oder Antwort zurück, die ihn erzeugt hat. Prüfen Sie, ob diese Quelle bereits dekodierten Text zurückgibt. Meldet sie bytes, ermitteln Sie die Kodierung der Quelle und dekodieren Sie den Wert dort, bevor er als Text behandelt wird. Leiten Sie den Typ nicht aus einem Variablennamen wie raw_data ab, sondern prüfen Sie das tatsächliche Objekt.
Wenn Daten mehrere Hilfsfunktionen durchlaufen, legen Sie deren Schnittstellenverträge eindeutig fest: Eine Funktion zur Textverarbeitung sollte str erhalten, eine Funktion zur Byteverarbeitung bytes. Eine Typannotation wie def parse_message(message: str) -> None: dokumentiert diese Erwartung, wandelt Werte zur Laufzeit jedoch nicht um. Kann eine Schnittstelle einen der beiden Typen zurückgeben, vereinheitlichen Sie den Typ einmal an dieser Schnittstelle und halten Sie den Rest des Programms konsistent.
Zusammengefasst: Python-3-Werte vom Typ str sind Text und besitzen keine Methode decode(). Entfernen Sie den Aufruf bei Text; dekodieren Sie bytes einmal dort, wo codierte Eingabedaten zu Text werden. So beheben Sie den konkreten Fehler und erhalten die beabsichtigte Unterscheidung zwischen Text und seiner Byte-Darstellung.