Ich verwende Pythons ftplib
, um einen kleinen FTP-Client zu schreiben, aber einige der Funktionen im Paket geben keine Zeichenfolgenausgabe zurück, sondern drucken anstdout
. Ich möchte zu stdout
einem Objekt umleiten , von dem ich die Ausgabe lesen kann.
Ich weiß, stdout
kann in jede reguläre Datei umgeleitet werden mit:
stdout = open("file", "a")
Ich bevorzuge jedoch eine Methode, bei der das lokale Laufwerk nicht verwendet wird.
Ich suche nach etwas wie dem BufferedReader
in Java, mit dem ein Puffer in einen Stream eingeschlossen werden kann.
stdout = open("file", "a")
allein etwas umleiten wird.Antworten:
quelle
stdout
, da es immer unter verfügbar istsys.__stdout__
. Siehe docs.python.org/library/sys.html#sys.__stdout__ .finally:
Block neu zuzuweisen , daher wird es auch neu zugewiesen, wenn dazwischen eine Ausnahme auftritt.try: bkp = sys.stdout ... ... finally: sys.stdout = bkp
In Python 3.4 gibt es die Funktion contextlib.redirect_stdout () :
Das folgende Codebeispiel zeigt, wie es in älteren Python-Versionen implementiert wird .
quelle
redirect_stderr
auf dem neuesten Python!Nur um Neds Antwort oben zu ergänzen: Sie können dies verwenden, um die Ausgabe an jedes Objekt umzuleiten , das eine write (str) -Methode implementiert .
Dies kann effektiv verwendet werden, um die Standardausgabe in einer GUI-Anwendung zu "fangen".
Hier ist ein dummes Beispiel in PyQt:
quelle
Ab Python 2.6 können Sie alles, was die
TextIOBase
API aus dem io-Modul implementiert, als Ersatz verwenden. Mit dieser Lösung können Sie auchsys.stdout.buffer.write()
in Python 3 (bereits) codierte Byte-Strings in stdout schreiben (siehe stdout in Python 3 ). Die VerwendungStringIO
würde dann nicht funktionieren, da wedersys.stdout.encoding
nochsys.stdout.buffer
verfügbar wäre.Eine Lösung mit TextIOWrapper:
Diese Lösung funktioniert für Python 2> = 2.6 und Python 3.
Bitte beachten Sie, dass unser neues
sys.stdout.write()
nur Unicode-Zeichenfolgen undsys.stdout.buffer.write()
nur Byte-Zeichenfolgen akzeptiert. Dies ist möglicherweise nicht der Fall für alten Code, aber häufig für Code, der für die Ausführung auf Python 2 und 3 ohne Änderungen erstellt wurde, was wiederum häufig verwendet wirdsys.stdout.buffer
.Sie können eine geringfügige Variation erstellen, die Unicode- und Byte-Zeichenfolgen akzeptiert für
write()
:Sie müssen die Codierung des Puffers nicht auf sys.stdout.encoding festlegen, dies ist jedoch hilfreich, wenn Sie diese Methode zum Testen / Vergleichen der Skriptausgabe verwenden.
quelle
Diese Methode stellt sys.stdout auch dann wieder her, wenn eine Ausnahme vorliegt. Es wird auch eine Ausgabe vor der Ausnahme erhalten.
Getestet in Python 2.7.10 mit
io.BytesIO()
Getestet in Python 3.6.4 mit
io.StringIO()
Bob, hinzugefügt für einen Fall, wenn Sie der Meinung sind, dass etwas aus dem Experiment mit modifiziertem / erweitertem Code in irgendeiner Weise interessant werden könnte. Andernfalls können Sie es jederzeit löschen
quelle
Ein Kontextmanager für Python3:
Verwendung wie folgt:
quelle
In Python3.6 sind die Module
StringIO
undcStringIO
weg. Sie sollten sieio.StringIO
stattdessen verwenden. Sie sollten dies also wie die erste Antwort tun:quelle
Verwenden Sie
pipe()
und schreiben Sie in den entsprechenden Dateideskriptor.https://docs.python.org/library/os.html#file-descriptor-operations
quelle
Hier ist eine andere Sichtweise.
contextlib.redirect_stdout
mitio.StringIO()
wie dokumentiert ist toll, aber es ist immer noch ein bisschen ausführlich für den täglichen Gebrauch. So machen Sie es durch Unterklassen zu einem Einzeilercontextlib.redirect_stdout
:Da __enter__ self zurückgibt, steht Ihnen das Kontextmanagerobjekt nach dem Beenden des Blocks zur Verfügung. Darüber hinaus ist dank der __repr__ -Methode die Zeichenfolgendarstellung des Kontextmanagerobjekts tatsächlich stdout. Also jetzt hast du,
quelle