Verwenden von Pipes, um Dinge, die in STDERR gedruckt wurden, in Python-Variablen von Jupyter zu erfassen

8

Ich versuche, die Dinge, die auf STDERR gedruckt werden, zu erfassen, wenn ich Befehle in jupyter Notebook ausführen. Insbesondere verwende ich TensorFlow, das fprintf von den C-Teilen ausgibt, das normalerweise auf der Konsole gedruckt wird, aber ich möchte in die Python-Variable speichern.

Ich habe FDRedirector aus der IPython-Codebasis verwendet, die setzt up os.pipe , um die Ausgabe in Python-String zu erfassen.

Das Problem mit diesem Code ist jedoch, dass der Kernel für eine ausreichend große Ausgabe hängen bleibt. Ich vermute, dass es für die Ausgabe über 65k hängt, da das die Pipe-Puffergröße unter Linux ist und gdb zeigt, dass der Hang in write passiert. Hat jemand eine Lösung, die mit größeren Ausgängen arbeiten würde?

Als Beispiel für das, was ich gerade mache, benutze FDRedirector

%Vor%

Am Ende enthält "captured_stderr" alle Dinge, die in stderr gedruckt wurden, einschließlich longstringlongstring . Wenn Sie longstring part viel länger machen (& gt; 100k), wird dies einfrieren.

    
Yaroslav Bulatov 19.12.2016, 05:26
quelle

4 Antworten

2

Sie können versuchen, Ihre Ausgabe in eine temporäre Datei zu leiten - also keine Pufferbeschränkungen:

%Vor%

Bitte lassen Sie mich wissen, ob dies für Ihren Zweck funktioniert. Leider habe ich TF nicht installiert.

Jupyter selbst überlebte die Ausgabe von 1 Mb zu einer Zelle:)

    
Ivan 23.12.2016 12:51
quelle
1

Das Problem mit FDRedirector ist, dass es nur einmal aus der Pipe gelesen wird. Da sowohl der Hersteller als auch das Verbraucherende der Leitung in demselben Prozess leben, wird dies das Schreibende der Leitung blockieren, sobald der Puffer voll ist. Die Lösung besteht darin, kontinuierlich vom Leseende zu lesen, um die andere Seite nicht zu blockieren. Eine Möglichkeit besteht darin, einen Consumer-Thread zu erstellen.

Hier ist ein Stück Code, der genau das tut: stderr zu einer Pipe umleiten und kontinuierlich mit einem Thread lesen.

Update : Der Code ist jetzt für Python 3, wie von OPs Kommentar vorgeschlagen. Angenommen, Sie möchten die erfasste Ausgabe in einer Python 3-Zeichenkette (d. H. Einer Unicode-Zeichenkette) haben, konvertiert redirect nun die gelesenen Bytes in eine Zeichenkette. Dafür akzeptiert sie encoding und errors Argumente - genau wie Pythons decode (und dieselben Standardwerte verwendend). Dies löst ein echtes Problem für den allgemeinen Anwendungsfall: Wenn Sie auf die erfassten Daten als String für die weitere Verarbeitung zugreifen möchten, müssen Sie wissen, in welche Kodierung stderr geschrieben wird. Dies gilt auch für die Vorgehensweise in der anderen Antwort, bei der der Stream in eine Datei umgeleitet wird. Wenn nur die Bytes in Ordnung sind, können Sie den Code ändern, um ein io.BytesIO zu verwenden.

%Vor%

Der redirect -Kontextmanager kann dann verwendet werden, um jeden Strom zeitweilig in einen internen Puffer umzuleiten. Beachten Sie, dass unter% jc_% sys.stderr nicht mit STDERR verbunden ist, es ist ein ipykernel.iostream.OutStream -Objekt, das ein Python file emuliert. Also müssen wir os.write auf STDERR setzen, um die Umleitung zu sehen.

%Vor%     
fpbhb 23.12.2016 12:51
quelle
0

hoffe, das wird für dich funktionieren

%Vor%     
Midhun Mohan 26.12.2016 09:46
quelle
0

Dieser Code versucht, Jupyter %%capture magic zu imitieren, indem er eine IPython.utils.capture.CapturedIO -Instanz zurückgibt.

Er verwendet tempfile.TemporaryFile , um die in stdout und stderr geschriebenen Bytes zu speichern. Die Methode __init__ stellt sicher, dass sys.stdout identisch mit sys.__stdout__ im Block with ist. Genauso verhält es sich mit sys.stderr . Die __exit__ -Methode synchronisiert zuerst Daten mit den temporären Dateien mit os.fdatasync , liest dann Bytes aus temporären Dateien und schreibt sie zurück in StringIO instance.

Die zurückgegebene IPython.utils.capture.CapturedIO instanz sport stdout , stderr Eigenschaft, eine show Methode und selbst ist aufrufbar.

%Vor%

Test;

%Vor%

Ausgabe;

%Vor%     
Nizam Mohamed 28.12.2016 20:58
quelle

Tags und Links