2017-12-14 4 views
0

Ich habe ein Basis-Python-Projekt, das andere Python-Dateien akzeptieren und als Unterprozess ausführen kann. Das Basisprojekt akzeptiert Benutzereingaben, führt sie dem Unterprozess zu, der dann Code ausführt, und gibt einen Wert über stdout zurück, der an den Benutzer zurückgegeben wird.Python Subprozess steuernden Ausgang

Im Basisprogramm, das ich auf etwas ähnliches tue:

dataReturnValue = subprocess.check_output(['python', pythonScriptPath, json.dumps(inputParams)]) 

dann im subprocess Ich habe so etwas wie dies:

inputParams = sys.argv[1] 
... 
... 
sys.stdout.write(returnValue) 

Die Daten korrekt zurückgegeben werden, aber was ich d mag es, wenn die zurückgegebenen Daten auf den returnValue beschränkt sind. Im Moment gibt es alle print-Anweisungen im Subprozess und den Rückgabewert zurück. Das macht für mich Sinn, da es sich um eine Ausgabeform handelt und der Ausdruck einem Standard-Wrapper ähnlich ist, aber ich möchte das besser kontrollieren.

Gibt es eine Möglichkeit, den Stdout-Puffer direkt vor meiner endgültigen Ausgabeanweisung zu löschen, so dass keine Streuausdrucke oder Ausgaben in dem vom Unterprozess zurückgegebenen Wert enthalten sind?

Edit: Ich habe versucht, eine sys.stdout.buffer.flush(), sys.stdout.flush() kurz vor dem letzten Aufruf in der Hoffnung, dass es den Puffer löschen würde, aber die print-Anweisungen noch vor scheinbar mit dem endgültigen Rückgabewert gesendet werden.

+0

Wenn es sich um ein Python-Skript handelt, ist die Verwendung von 'subprocess' möglicherweise nicht der beste Weg. Wenn Sie sich diesem Ansatz verschrieben haben, sollten Sie vielleicht einen Sentinel-Wert drucken, der ein Trennzeichen ist.Zum Beispiel 'print ('SENTINEL', end = '')' und dann 'value = dataReturnValue.split ('SENTINEL') [- 1]' - Aber im Idealfall willst du nur das Skript importieren und die Funktionen aufrufen . – sytech

Antwort

1

Try this:

import sys 
import os 

# Your code here 

with open(os.devnull, 'w') as sys.stdout: 
    # Code that you don't want to be printed here 
sys.stdout = sys.__stdout__ 

# Your code here 

Edit:

ich auch machte es zu einem Dekorateur für dich

import sys 
import os 

def silence(func, *args, **kwargs): 
    def wrapper(*args, **kwargs): 
     with open(os.devnull, 'w') as sys.stdout: 
      result = func(*args, **kwargs) 
     sys.__dict__['stdout'] = sys.__stdout__ 
     return result 
    return wrapper 

es auf jede Funktion wie folgt verwendet:

def test1(): 
    print("TEST1") 

@silence 
def test2(): 
    print("TEST2") 

def test3(): 
    print("TEST3") 

test1() 
test2() 
test3() 

Ausgang:

TEST1 
TEST3 
+0

teilen kann, das tatsächlich keine Fehler zurückgibt, aber es gibt auch keine Ausgabe zurück, da ich möchte, dass stdout für die letzte verfügbar ist Ausgabeaufruf –

+0

Ich bin auch besorgt, dass Unordnung mit dem Öffnen und Schließen des Stdout-Puffers wird mit irgendwelchen Referenzen zwischen dem Hauptprozess und Subprozess übergeben –

+0

Ich habe es bearbeitet, um darauf aufzupassen. Lassen Sie mich wissen, ob das für Sie funktioniert. –

0

könnte dies nicht die Antwort sein, die Sie suchen, aber vielleicht ist dies eine mögliche Abhilfe:

dataReturnValue = dataReturnValue.split("\n")[-1]

+0

dieser arbeitet als Workaround, zumindest bei einfachen Ausgaben, aber ich mache mir Sorgen, wenn Daten, die ich zurückgeben möchte, enthält tatsächlich \ n dann wird es nur ein Segment der gewünschten Ausgabe und nicht alles zurückgeben. Es hat mich denken lassen, als eine geringfügige Änderung, dass vielleicht könnte ich einen bestimmten Schlüssel der Datenausgabe vorangestellt haben, die ich durch –

0

Kann dies Ihnen helfen können.

Sie können subprocess Popen verwenden, PIPE Ihre task.if tun möchten Sie hier mehrere subprocess Instanzen verwenden, ist der Link

Python subprocess: how to use pipes thrice?

Wie die Ausgabe zu kontrollieren?

unter Befehl (Dummy-Kommando) werden 100 Zeilen erzeugen, aber ich brauche nur eine Zeile, die Text haben ‚Appium Started‘

from subprocess import Popen,PIPE 
command='appium-p 4723' 
p1=Popen(command,stdout=Pipe) 

return_value= 'Started Appium' 

#this will store the output which command generated 
output = p3.communicate()[0] 

for line in output: 
    if returnvalue in line: 
     print line 
    else: 
     pass 

am Ende nur die Zeile erhalten, die Sie wollten also Appium Gestartet