Ich verwende eine Python-Bibliothek, die etwas mit einem Objekt macht
do_something(my_object)
und ändert es. Dabei werden einige Statistiken an stdout gedruckt, und ich möchte diese Informationen in den Griff bekommen. Die richtige Lösung wäre, zu ändern do_something()
, um die relevanten Informationen zurückzugeben.
out = do_something(my_object)
Aber es wird eine Weile dauern, bis die Entwickler do_something()
zu diesem Thema kommen. Um dieses Problem do_something()
zu umgehen , habe ich darüber nachgedacht, alles zu analysieren, was in stdout geschrieben wird.
Wie kann ich die Standardausgabe zwischen zwei Punkten im Code erfassen, z.
start_capturing()
do_something(my_object)
out = end_capturing()
?
Antworten:
Versuchen Sie diesen Kontextmanager:
Verwendung:
output
ist jetzt eine Liste mit den vom Funktionsaufruf gedruckten Zeilen.Erweiterte Verwendung:
Was möglicherweise nicht offensichtlich ist, ist, dass dies mehr als einmal durchgeführt und die Ergebnisse verkettet werden können:
Ausgabe:
Update : Sie fügten hinzu ,
redirect_stdout()
umcontextlib
in Python 3.4 (zusammen mitredirect_stderr()
). Sie könnten damitio.StringIO
ein ähnliches Ergebnis erzielen (obwohlCapturing
es wohl bequemer ist, sowohl eine Liste als auch ein Kontextmanager zu sein).quelle
.extend()
stattdessen verwendet, damit er verkettet verwendet werden kann, genau wie Sie es bemerkt haben. :-)self._stringio.truncate(0)
nach demself.extend()
Aufruf der__exit__()
Methode ein Element hinzuzufügen, um einen Teil des vom_stringio
Mitglied gespeicherten Speichers freizugeben .from io import StringIO
anstelle der ersten Zeile im Kontextmanager.In Python> = 3.4 enthält contextlib einen
redirect_stdout
Dekorator. Es kann verwendet werden, um Ihre Frage wie folgt zu beantworten:Aus den Dokumenten :
quelle
f = io.StringIO() with redirect_stdout(f): logger = getLogger('test_logger') logger.debug('Test debug message') out = f.getvalue() self.assertEqual(out, 'DEBUG:test_logger:Test debug message')
. Es gibt mir einen Fehler:AssertionError: '' != 'Test debug message'
logger.debug
schreibt standardmäßig nicht in stdout. Wenn Sie Ihren Protokollanruf durch ersetzenprint()
, sollte die Meldung angezeigt werden.stream_handler = logging.StreamHandler(sys.stdout)
. Und fügen Sie diesen Handler meinem Logger hinzu. also sollte es an stdout schreiben undredirect_stdout
es fangen, oder?Hier ist eine asynchrone Lösung mit File Pipes.
Anwendungsbeispiel:
quelle