To main content

Python3, sys.stdin und encoding-Mischmasch

Veröffentlicht von Benjamin Marwell am

Wer in python2 bereits folgendes Konstrukt verwendete, brauchte sich über Encodings (Zeichenkodierung)  keine Gedanken zu machen:

for line in sys.stdin:

Leider funktioniert dieses Konstrukt in python3 nicht mehr. Bei verschiedenen Encodings (bzw. kein UTF-8) erhält man folgende Exception:

UnicodeDecodeError: 'utf8' codec can't decode bytes
Kommen Zeichen in der Eingabe vor, die nicht mit UTF-8 kodiert sind, so kann man entweder mit einem try... except-Konstrukt diese Zeile ignorieren oder - besser - die Eingabedatei als Bytesequenz einlesen:
for line in sys.stdin.buffer.readlines():
    line = str(line)

Nun erhält man Bytesequenzen (Typ: bytes), in dem alle nicht-ASCII-Zeichen escaped sind. Möchte man stattdessen normale Strings haben, geht man so vor:

try:
    line = line.decode()
except:
    #print("böses zeichen")
    try:
        line = line.decode('latin1')
    except:
        #print("ganz böses Zeichen")
        line = str(line)
line = line.rstrip('\n')

Und so weiter, für jeden erdenklichen Zeichensatz. Möchte man auf Teufel-komm-raus den richtigen Zeichensatz erhaschen, baut man sich am besten eine Schleife mit einer Liste von Zeichensätzen.

So kommt man aber zumindest zu dem Ergebnis, dass man ein funktionierendes Programm behält und ungewöhnliche Zeichensätze ignoriert werden.