Wie Python-Interpreter und / oder CMD.EXE Ausgabe von einem Python-Skript zu erfassen?

StackOverflow https://stackoverflow.com/questions/24931

  •  09-06-2019
  •  | 
  •  

Frage

  1. Ist es möglich, Python-Interpreter Ausgabe von einem Python-Skript zu erfassen?
  2. Ist es möglich, Windows CMD Ausgabe von einem Python-Skript zu erfassen?

Wenn ja, welche librar? (Y | n) soll ich in aussehen

War es hilfreich?

Lösung

Wenn Sie über den Python-Interpreter oder CMD.exe sprechen, dass die ‚Eltern‘ des Skriptes ist dann nicht, ist es nicht möglich. In jedem POSIX-artigen System (jetzt laufen Sie Windows, wie es scheint, und das könnte einige Marotte ich weiß, hat nicht etwa, YMMV) jeder Prozess hat drei Ströme, Standardeingabe, Standardausgabe und Standardfehler. Bu default (wenn sie in einer Konsole ausgeführt wird), diese an der Konsole gerichtet sind, aber die Umleitung ist möglich, die Rohr Notation:

python script_a.py | python script_b.py

Dies bindet die Standardausgabe des Skripts ein, um den Standardeingabestrom von Skript B. Standardfehler geht noch auf die Konsole in diesem Beispiel. Siehe den Artikel über Standard-Streams auf Wikipedia.

Wenn Sie sich über ein Kind Prozess sprechen, können Sie es aus Python wie so starten (stdin ist auch eine Option, wenn Sie zwei-Wege-Kommunikation wollen):

import subprocess
# Of course you can open things other than python here :)
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
x = process.stderr.readline()
y = process.stdout.readline()
process.wait()

Sehen Sie die Python subprocess Modul für Informationen über den Prozess zu verwalten. Für die Kommunikation werden die process.stdin und process.stdout Rohre Standard Dateiobjekte rel="nofollow .

Für die Verwendung mit Rohren, von der Standardeingabe zu lesen: lassevk vorgeschlagen, dass Sie so etwas tun würde:

import sys
x = sys.stderr.readline()
y = sys.stdin.readline()

sys.stdin und sys.stdout sind Standarddateiobjekte wie oben erwähnt, in der sys Modul. Vielleicht haben Sie auch einen Blick auf die Rohre Modul nehmen wollen.

Beim Lesen von Daten mit Readline- (), wie in meinem Beispiel ist eine ziemlich naive Art und Weise, obwohl Daten zu bekommen. Ist der Ausgang nicht zeilenorientiert oder indeterministischen Sie wahrscheinlich wollen schauen Sie in Polling welche funktioniert leider nicht in den Fenstern, aber ich bin sicher, dass da draußen einige alternative gibt.

Andere Tipps

Ich denke, dass ich Ihnen eine gute Antwort für den ersten Teil Ihrer Frage verweisen.

  

1. Ist es möglich, Python-Interpreter Ausgabe von einem Python zu erfassen   Skript?

Die Antwort ist " ja ", und persönlich mag ich die folgenden aus den Beispielen in der PEP 343 - Das "mit" Statement Dokument

from contextlib import contextmanager
import sys

@contextmanager
def stdout_redirected(new_stdout):
    saved_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout.close()
        sys.stdout = saved_stdout

Und wie folgt verwendet:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

Ein schöner Aspekt davon ist, dass es selektiv um nur einen Teil eines Ausführung des Skripts angewendet werden kann, anstatt seinem ganzen Umfang und bleibt wirksam, auch wenn nicht behandelte Ausnahmen in seinem Kontext erhoben werden. Wenn Sie die Datei im Append-Modus nach dem ersten Gebrauch wieder öffnen, können Sie die Ergebnisse in eine einzige Datei akkumulieren:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

print "screen only output again"

with stdout_redirected(open("filename.txt", "a")):
    print "Hello world2"

Natürlich könnte die oben auch erweitert werden, um auch sys.stderr auf die gleiche oder eine andere Datei zu umleiten. Siehe auch diese beantworten zu einer verwandten Frage.

Eigentlich Sie auf jeden Fall können, und es ist schön, hässlich, und verrückt zugleich!

Sie können sys.stdout und sys.stderr mit StringIO Objekte ersetzen, die die Ausgabe sammeln.

Hier ist ein Beispiel, es als evil.py speichern:

import sys
import StringIO

s = StringIO.StringIO()

sys.stdout = s

print "hey, this isn't going to stdout at all!"
print "where is it ?"

sys.stderr.write('It actually went to a StringIO object, I will show you now:\n')
sys.stderr.write(s.getvalue())

Wenn Sie dieses Programm ausführen, sehen Sie, dass:

  • nichts ging nach stdout (wo Druck in der Regel druckt)
  • die erste Zeichenfolge, die auf stderr geschrieben wird ist die mit ‚Es‘
  • Start
  • die nächsten beiden Zeilen sind diejenigen, die in der StringIO Objekt gesammelt wurden

Ersetzen sys.stdout / wie diese Irren ist eine Anwendung von dem, was monkeypatching genannt wird. Meinungen können variieren, ob dies wird ‚unterstützt‘, und es ist auf jeden Fall ein hässlicher Hack, aber es hat meinen Speck gerettet, wenn sich um externe Sachen ein- oder zweimal zu wickeln versucht.

Getestet unter Linux, nicht auf Windows, aber es sollte genauso gut funktionieren. Lassen Sie mich wissen, ob es funktioniert auf Windows!

Sie wollen subprocess . Schauen Sie sich speziell an Popen in 17.1.1 und 17.1.2 kommunizieren.

In diesem Zusammenhang fragen Sie?

Sind Sie versuchen, den Ausgang von einem Programm, das Sie auf der Kommandozeile starten zu erfassen?

Wenn ja, dann ist dies, wie es auszuführen:

somescript.py | your-capture-program-here

und die Ausgabe zu lesen, nur von der Standardeingabe lesen.

Wenn auf der anderen Seite, die Sie ausführen das Skript oder cmd.exe oder ähnliches aus Ihrem Programm und wollen warten, bis das Skript / Programm beendet ist, und erfassen alle seine Ausgabe, dann müssen Sie schauen in der Bibliothek Anrufe verwenden, um Sie zu beginnen, dass externes Programm, höchstwahrscheinlich es eine Möglichkeit, es zu fragen Sie eine Möglichkeit zu geben, die Ausgabe und warten auf Abschluss zu lesen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top