/ / python utf-8-Codierung löst UnicodeDecodeError trotz „errors = 'replace'“ aus - Python, encoding, utf-8, cp1252

Python UTF-8-Codierung löst UnicodeDecodeError trotz "errors = 'replace" aus - Python, Encoding, utf-8, cp1252

Ich versuche, etwas Text herauszuschreiben und, wo möglich, als utf-8 zu kodieren, wobei ich folgenden Code verwendet:

outf.write((lang_name + "," + (script_name or "") + "n").encode("utf-8", errors="replace"))

Ich erhalte den folgenden Fehler:

File "C:Python27libencodingscp1252.py", line 15, in decode
return codecs.charmap_decode(input,errors,decoding_table)
UnicodeDecodeError: "charmap" codec can"t decode byte 0x81 in position 6: character maps to <undefined>

Ich dachte das errors="replace" würde mein codierungsaufruf das erledigen?

fwiw, ich öffne gerade die Datei mit

outf = open(outfile, "w")

ohne die Kodierung explizit zu deklarieren.

print repr(outf)

produziert:

<open file "myfile.csv", mode "w" at 0x000000000315E930>

Ich habe die Schreibanweisung in eine separate Verkettung, Codierung und Dateischreibung aufgeteilt:

outstr = lang_name + "," + (script_name or "") + "n"
encoded_outstr = outstr.encode("utf-8", errors="replace")
outf.write(encoded_outstr)

Es ist die Verkettung, die die Ausnahme auslöst.

Die Zeichenfolge ist via print repr(foo)

lang_name: "Gxc4x81ndhxc4x81rxc4xab"
script_name: u"Kharou1e63u1e6dhu012b"

Weitere Detektivarbeiten zeigen, dass ich eine von denen mit einer einfachen Ascii-Saite problemlos verketten kann - es werden beide in dieselbe Saite gesetzt, die die Dinge kaputt macht.

Antworten:

1 für die Antwort № 1

Das Problem ist also, dass Sie den Bytestring verketten "Gxc4x81ndhxc4x81rxc4xab" und die Unicode-Zeichenfolge u"Kharou1e63u1e6dhu012b".

Um dies tun zu können, muss Python 2.7 versucht, den Bytestring mit seiner Standardcodierung zu decodieren, um daraus Unicode zu machen. Ihre Standardcodierung ist cp1252 anstelle von ASCII. Aus Gründen, die ich hier nicht kennen kann, schlägt sie fehl, genauso wie es ASCII gewesen wäre, weil es sich bei diesem String um UTF8 handelt.

Die beste Lösung besteht wahrscheinlich darin, sicherzustellen, dass dies nicht geschieht, indem Sie die Art und Weise ändern, auf die die Variablen diese Werte erhalten.

Wenn Sie nicht in der Lage sind, UTF8 in der nächsten Zeile zu codieren, ist es wahrscheinlich am einfachsten, nur script_name zu codieren:

encoded_outstr = lang_name + b"," + (script_name.encode("utf-8") or b"") + b"n"

Beachten Sie, dass ich verwendet habe b"," diese Zeichenfolgenliterale explizit als Zeichenfolgen und nicht als Unicode-Zeichenfolgen definieren; wenn du verwendest from __future__ import unicode_literals Für die Python 3-Kompatibilität sind sie standardmäßig Unicode und das Problem würde nur wieder auftreten.


1 für die Antwort № 2

Wenn Sie einen Byte- und einen Unicode-String verketten, versucht Python 2, den Byte-String zuerst in Unicode zu konvertieren. Wenn die Bytezeichenfolge Nicht-ASCII-Zeichen im Bereich von enthält x80 zu xffDie automatische Konvertierung schlägt mit dem angezeigten Fehler fehl. Beachten Sie, dass es sagt can"t decodenicht can"t encode - Dies zeigt, dass der Fehler aufgetreten ist nicht treten in Ihrem Anruf auf encode.

Die Lösung ist zu decode Die Byte-Zeichenfolge wird mithilfe der richtigen Codepage in Unicode eingefügt, sodass alle Eingaben für die Verkettung Unicode-Zeichenfolgen sind.

outstr = lang_name.decode("utf-8") + u"," + (script_name or u"") + u"n"