Python 3 TypeError: muss str sein, nicht Bytes mit sys.stdout.write ()
War ich auf der Suche nach einem Weg, um ein externes Prozess-von der python-Skript-und print-seine stdout Nachrichten während der Ausführung.
Der untenstehende code funktioniert, aber druckt keine stdout-Ausgabe während der Laufzeit. Wenn er beendet wird, erhalte ich die folgende Fehlermeldung:
sys.stdout.schreiben(nextline -) TypeError:must be str,nicht bytes
p = subprocess.Popen(["demo.exe"],stdout = subprocess.PIPE, stderr= subprocess.PIPE)
# Poll process for new output until finished
while True:
nextline = p.stdout.readline()
if nextline == '' and p.poll() != None:
break
sys.stdout.write(nextline)
sys.stdout.flush()
output = p.communicate()[0]
exitCode = p.returncode
Ich bin mit python 3.3.2
InformationsquelleAutor der Frage Michael IV | 2014-02-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Python 3 behandelt strings ein wenig anders. Ursprünglich gab es nur einen Typ für
Streicher:
str
. Wenn unicode gewonnen Traktion in den 90er Jahren die neueunicode
gebenwurde Hinzugefügt, um den Umgang mit Unicode, ohne zu brechen pre-existing code1. Dies ist
effektiv das gleiche wie
str
aber mit multibyte-support.In Python 3 gibt es zwei verschiedene Arten:
bytes
geben. Dies ist nur eine Folge von bytes, Python nicht kenntalles darüber, wie Sie zu interpretieren dies als Zeichen.
str
geben. Dies ist auch eine Folge von bytes, aber Python weiß, wieinterpretiert diese bytes als Zeichen.
unicode
Typ wurde gelöscht.str
unterstützt jetzt unicode.In Python 2 implizit vorausgesetzt, eine Codierung könnte eine Menge Probleme verursachen; Sie
konnte am Ende mit der falschen Codierung, oder die Daten können nicht über eine Codierung an
alle (es ist z.B. ein PNG-Bild).
Explizit sagen, Python, welche Codierung zu verwenden (oder explizit sagen,
erraten) ist oft viel besser und viel mehr im Einklang mit der "Python-Philosophie"
"explizit ist besser als implizit".
Diese änderung ist nicht kompatibel mit Python 2 wie viele Rückgabewerte geändert haben
was zu subtilen Problemen wie diesem; es ist wahrscheinlich der Hauptgrund, warum
Python 3 Annahme hat sich so langsam. Da Python nicht statische Typisierung2
es ist unmöglich, dies zu ändern, werden automatisch mit einem Skript (wie den in einem Bundle
2to3
).str
zubytes
mitbytes('h€llo', 'utf-8')
; dies sollteproduzieren
b'H\xe2\x82\xacllo'
. Beachten Sie, wie einer Charakter konvertiert wurde, um dreibytes.
bytes
zustr
mitb'H\xe2\x82\xacllo'.decode('utf-8')
.Natürlich UTF-8 möglicherweise nicht den richtigen Zeichensatz in deinem Fall so sicher sein
verwenden Sie die richtige.
In Ihrem speziellen Stück code,
nextline
ist der Typbytes
nichtstr
Lesen
stdout
undstdin
aussubprocess
geändert in Python 3 vonstr
zubytes
. Dies ist, weil Python kann nicht wissen, in welcher Kodierung diese verwendet. Eswahrscheinlich verwendet die gleichen wie
sys.stdin.encoding
(Codierung system),aber es kann nicht sicher sein.
Müssen Sie ersetzen:
mit:
oder vielleicht:
Müssen Sie auch ändern
if nextline == ''
zuif nextline == b''
seit:Siehe auch die Python 3 ChangeLogPEP 358und PEP 3112.
1 Es gibt einige nette tricks, die Sie tun können, mit ASCII -, dass man nicht auch mit multibyte-Zeichensätzen; das berühmteste Beispiel ist die "xor mit Raum zu switch case" (z.B.
chr(ord('a') ^ ord(' ')) == 'A'
) und "gesetzt 6. bit, um ein steuerzeichen" (z.B.ord('\t') + ord('@') == ord('I')
). ASCII wurde entwickelt, in einer Zeit, als das manipulieren von einzelnen bits wurde ein Betrieb mit einer nicht unerheblichen Auswirkungen auf die Leistung.2 - ja, Sie können verwenden Funktion Anmerkungen, aber es ist eine vergleichsweise neue Funktion und wenig benutzt.
InformationsquelleAutor der Antwort Martin Tournoij
Während die akzeptierte Antwort wird funktionieren, wenn die bytes, die Sie von Ihrer Teilprozess codiert werden mit
sys.stdout.encoding
(oder eine kompatible Codierung, wie das Lesen von einem Werkzeug, dass die Ausgänge ASCII und Ihr stdout verwendet UTF-8), die richtige Art und Weise zu schreiben, die beliebige bytes auf stdout ist:Nur die Ausgabe der bytes, wie Sie ist, ohne zu versuchen, Sie zu behandeln, als text-in-einige-Codierung.
InformationsquelleAutor der Antwort geoffspear