Ich arbeite an einem Datensatz von einem MOOC. Ich habe eine Menge von python3-Code-Schnipsel, die ich ausführen muss und die Ergebnisse von erhalten. Um dies zu tun, habe ich ein Python-Skript geschrieben, das jedes Snippet durchläuft. Für jedes Snippet I:
sys.stdout
und sys.stderr
auf meine stringIO Puffer threading.thread
-Objekt Das funktioniert gut für "richtigen" Code, aber das hat in anderen Fällen Probleme:
print()
hat, beginnt der Thread, mein tatsächliches stdout zu überschreiben, wenn ich es auf den Standardwert zurücksetze (weg vom StringIO-Puffer). Dies belastet meine Berichterstattung. Hier ist mein aktueller Code:
%Vor% Um diesen Fall zu behandeln, habe ich versucht, multithreading.Process
und / oder contextlib.redirect_stdout
zu verwenden, um den Code in einem Prozess auszuführen (dann kann ich process.terminate()
aufrufen), aber ich habe keine Erfolgserfassung stdout / stderr.
Meine Frage ist also: Wie kann ich stdout / stderr von einem Prozess umleiten oder aufzeichnen? Oder gibt es eine andere Möglichkeit, die Ausgabe von beliebigem Code auszuführen und zu erfassen?
(Und ja, ich weiß, dass das im Allgemeinen eine schlechte Idee ist; ich benutze es in einer virtuellen Maschine, nur für den Fall, dass sich irgendwo Schadcode befindet)
Python-Version ist 3.5.3
Mir fällt auf, dass es in dieser Situation etwas mehr Flexibilität gibt. Ich habe eine Funktion, preprocess(code)
, die einen Code als String akzeptiert und ändert. Meistens habe ich es benutzt, um den Wert einiger Variablen mit regulären Ausdrücken auszutauschen.
Hier ist eine Beispielimplementierung:
%Vor%Ich könnte die Vorverarbeitungsfunktion verwenden, um STDOUT
umzuleitenDie Kommunikation mit dem laufenden Prozess ist in Python nicht einfach. Aus irgendeinem Grund können Sie dies nur einmal im Subprozesslebenszyklus tun. Aus meiner Erfahrung ist es am besten, einen Thread zu starten, der einen Prozess startet und nach Timeout seine Ausgabe erhält und den Subprozess beendet.
Etwas wie:
%Vor% So, führen Sie einen Thread-Scharfrichter, der subprocess_with_timeout
aufruft. Es sollte die Eingaben verarbeiten und die Ergebnisse speichern.
Eine andere Idee ist die Verwendung eines Webservers für die IPC. Siehe diesen Link
Was ist mit subprocess.check_output
? Sie könnten python -c {snippet}
damit aufrufen, oder wenn es länger ist, schreiben Sie das Snippet in eine temporäre .py
-Datei. check_output
(und alle anderen Funktionen in subprocess
) haben einen timeout
-Parameter.
Die allgemeine Idee ist dann:
%Vor%Beispiel läuft in IPython:
%Vor% Beachten Sie, dass check_output
eine bytes
Sequenz zurückgibt, also müssen Sie sie in str
umwandeln. Oder Sie können den Parameter encoding
von check_output
verwenden.
Tags und Links python multithreading python-3.x stdout