Python 3 behandelt Strings etwas anders. Ursprünglich gab es nur einen Typ für Zeichenfolgen : str. Als Unicode in den 90er Jahren an Bedeutung gewann, wurde der neue unicodeTyp hinzugefügt, um Unicode zu handhaben, ohne den bereits vorhandenen Code 1 zu beschädigen . Dies ist praktisch dasselbe wie, strjedoch mit Multibyte-Unterstützung.
In Python 3 gibt es zwei verschiedene Typen:
- Der
bytesTyp. Dies ist nur eine Folge von Bytes. Python weiß nichts darüber, wie man dies als Zeichen interpretiert.
- Der
strTyp. Dies ist auch eine Folge von Bytes, aber Python weiß, wie diese Bytes als Zeichen interpretiert werden .
- Der separate
unicodeTyp wurde gelöscht. strunterstützt jetzt Unicode.
In Python 2 kann die implizite Annahme einer Codierung viele Probleme verursachen. Möglicherweise verwenden Sie die falsche Codierung, oder die Daten haben möglicherweise überhaupt keine Codierung (z. B. ein PNG-Bild).
Python explizit zu sagen, welche Codierung verwendet werden soll (oder explizit zu raten), ist oft viel besser und entspricht viel mehr der "Python-Philosophie" von " explizit ist besser als implizit ".
Diese Änderung ist nicht mit Python 2 kompatibel, da sich viele Rückgabewerte geändert haben, was zu subtilen Problemen wie diesem führt. Dies ist wahrscheinlich der Hauptgrund, warum die Einführung von Python 3 so langsam war. Da Python keine statische Typisierung 2 hat, ist
es unmöglich, dies automatisch mit einem Skript (wie dem gebündelten 2to3) zu ändern
.
- Sie können konvertieren
strzu bytesmit bytes('h€llo', 'utf-8'); das sollte produzieren b'H\xe2\x82\xacllo'. Beachten Sie, wie ein Zeichen in drei Bytes konvertiert wurde.
- Sie können konvertieren
byteszu strmit b'H\xe2\x82\xacllo'.decode('utf-8').
Natürlich ist UTF-8 in Ihrem Fall möglicherweise nicht der richtige Zeichensatz. Verwenden Sie daher unbedingt den richtigen.
In Ihrem spezifischen Code nextlineist vom Typ bytes, nicht strvom Lesen stdoutund stdinvon subprocessin Python 3 von strbis
geändert bytes. Dies liegt daran, dass Python nicht sicher sein kann, welche Codierung dies verwendet. Es verwendet
wahrscheinlich dasselbe wie sys.stdin.encoding(die Codierung Ihres Systems), kann aber nicht sicher sein.
Sie müssen ersetzen:
sys.stdout.write(nextline)
mit:
sys.stdout.write(nextline.decode('utf-8'))
oder vielleicht:
sys.stdout.write(nextline.decode(sys.stdout.encoding))
Sie werden auch ändern müssen , if nextline == ''um if nextline == b''da:
>>> '' == b''
False
Siehe auch Python 3 ChangeLog , PEP 358 und PEP 3112 .
1 Es gibt einige nette Tricks, die Sie mit ASCII machen können, die Sie mit Multibyte-Zeichensätzen nicht machen können. Das bekannteste Beispiel ist das "xor mit Leerzeichen zum Umschalten der Groß- chr(ord('a') ^ ord(' ')) == 'A'und Kleinschreibung" (z. B. ) und "Setzen Sie das 6. Bit, um ein Steuerzeichen zu erstellen" (z ord('\t') + ord('@') == ord('I'). B. ). ASCII wurde in einer Zeit entwickelt, in der die Manipulation einzelner Bits eine Operation mit nicht zu vernachlässigenden Auswirkungen auf die Leistung war.
2 Ja, Sie können Funktionsanmerkungen verwenden, aber es ist eine vergleichsweise neue Funktion, die nur wenig verwendet wird.