Unterdrücken stdout / stderr drucken von Python-Funktionen
Habe ich ein Python-Skript, das über einige closed-box Python-Funktionen (d.h. ich kann nicht diese Funktionen Bearbeiten) zur Verfügung gestellt von meinem Arbeitgeber. Wenn ich diese Funktionen aufrufen, Sie drucken die Ausgabe auf meinem linux-terminal, das würde ich gerne unterdrücken. Ich habe versucht, die Umleitung von stdout /stderr über;
orig_out = sys.stdout
sys.stdout = StringIO()
rogue_function()
sys.stdout = orig_out
aber dies nicht gelingt, fangen die Ausgabe. Ich denke, die Funktionen rufe ich über-Python (rogue_function() von oben) sind echt Wrapper für kompilierte C-code, die tatsächlich tun, die Sie drucken.
Kennt jemand eine Möglichkeit, ich kann ein "tief-erfassen" von jedem Druck übergeben stdout /stderr von einer Funktion (und alle sub-Funktionen, Funktionsaufrufe)?
UPDATE:
Ich landete dabei die beschriebene Methode in der gewählten Antwort unten schreiben und Kontext-manager zu unterdrücken stdout und stderr:
# Define a context manager to suppress stdout and stderr.
class suppress_stdout_stderr(object):
'''
A context manager for doing a "deep suppression" of stdout and stderr in
Python, i.e. will suppress all print, even if the print originates in a
compiled C/Fortran sub-function.
This will not suppress raised exceptions, since exceptions are printed
to stderr just before a script exits, and after the context manager has
exited (at least, I think that is why it lets exceptions through).
'''
def __init__(self):
# Open a pair of null files
self.null_fds = [os.open(os.devnull,os.O_RDWR) for x in range(2)]
# Save the actual stdout (1) and stderr (2) file descriptors.
self.save_fds = [os.dup(1), os.dup(2)]
def __enter__(self):
# Assign the null pointers to stdout and stderr.
os.dup2(self.null_fds[0],1)
os.dup2(self.null_fds[1],2)
def __exit__(self, *_):
# Re-assign the real stdout/stderr back to (1) and (2)
os.dup2(self.save_fds[0],1)
os.dup2(self.save_fds[1],2)
# Close all file descriptors
for fd in self.null_fds + self.save_fds:
os.close(fd)
Verwenden diese Sie nur:
with suppress_stdout_stderr():
rogue_function()
Das funktioniert "richtig gut". Es zu unterdrücken, den Ausdruck aus dem Schurken-Funktionen wurden überladen bis mein Skript. Bemerkte ich in Tests, dass durch die ausgelösten exceptions sowie einige logger drucken, und ich bin mir nicht ganz klar, warum. Ich denke es hat etwas zu tun mit wenn diese Nachrichten gesendet werden, um stdout /stderr (ich denke, es geschieht nach meinem Kontext-manager beendet). Wenn jemand das bestätigen können, ich wäre daran interessiert zu hören, die details ...
Statt der Einstellung
sys.stdout
zu StringIO()
, haben Sie versucht, die Einstellung in einer Datei? also sys.stdout = open('log.txt','w')
Dougal, danke, das sieht vielversprechend aus, ich werde es versuchen, morgen. nullpointer, ich habe versucht, lenkt Sie auf eine benutzerdefinierte NullPointer () - Klasse, und das hat nicht funktioniert entweder.
danke, das hat funktioniert! Wenn Sie so geneigt sind, zu posten, dass der link als Antwort und ich werde es auszuwählen.
Frage mich, ob es ist ein Weg, zu unterdrücken, alle - Ausgabe, nicht nur die Ausgabe, die kommt von C-code. Ich würde erwarten, dass wenn ich in dem Kontext mit suppress_stdout_stderr(), dann werden alle Ausgabe sollte abgefangen werden. Irgendwelche Ideen?
InformationsquelleAutor jeremiahbuddha | 2012-06-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dieser Ansatz (zu finden über die related Links) arbeiten könnte. Es ordnet die Datei-Deskriptoren, statt nur die Wrapper um Sie in sys.stdout, etc.
InformationsquelleAutor Dougal
Als python 3.5 wir können dies tun, mit minimaler Arbeit über built-ins in
contextlib
, nämlichredirect_stdout
undredirect_stderr
. Wir brauchen nur die Kombination dieser beiden built-in-context-Manager in ein eigenes Kontext-manager der unsrigen, der kann leicht getan werden mit das schöne Muster im Martijn Antwort hier. Umleitung der beiden Ausgänge zuos.devnull
sollte sicher und portabel genug.Beachten Sie, dass die Unterdrückung
stderr
immer noch geben Ihnen die volle tracebacks, wenn etwas bricht, das ist eine gute Sache:Wenn die oben genannten druckt nur
dem terminal. Unbehandelte Ausnahmen sollten nie unbemerkt.
InformationsquelleAutor Andras Deak
Meine Lösung ist ähnlich wie deins, aber verwendet
contextlib
und ist ein wenig kürzer und leichter zu verstehen (IMHO).Den Kontext, warum ich erstellt, dies ist bei in diesem blog-post. Ähnlich wie deins, denke ich.
Ich es verwenden, wie dies in einer
setup.py
:InformationsquelleAutor Marc Abramowitz
Haben Sie versucht, umleiten von stderr zu?
z.B.
Auch mit StringIO möglicherweise zusätzlichen Speicher. Sie können eine dummy-Gerät statt (z.B. http://coreygoldberg.blogspot.com/2009/05/python-redirect-or-turn-off-stdout-and.html).
Es könnte sein, dass die C-code schreibt direkt auf die Standardausgabe; Sie würde wahrscheinlich nicht in der Lage, umzuleiten. Sorry.
Sind diese kompatibel mit Python 3?
InformationsquelleAutor Bob
Nicht wirklich, angefordert durch die OP, aber ich musste verstecken und speichern den Ausgang, und habe Sie wie folgt vor:
Verwendung:
(getestet nur mit Python 3)
EDIT: jetzt können Sie wählen
stderr
,stdout
oder beides, wie inHider([stdout, stderr])
verallgemeinert ein bisschen, danke für die Anregung
InformationsquelleAutor Pietro Battiston
Benutze ich einen Dekorator für diese. Es spart
sys.stdout
undsys.stderr
Referenzen und macht diese Variablen zeigen auf null. Dann, nach der Ausführung der Funktion die ursprünglichen Referenzen abgerufen werden. Es ist wichtig zu beachten, dass die try-except-block, ermöglicht den Abruf des ursprünglichen Referenzen, selbst wenn eine Ausnahme ausgelöst wird, die auf die Funktion.Verwenden:
InformationsquelleAutor Vítor Cézar
python 3.6 funktionierende version, getestet mit Millionen Unterdrückungen ohne Fehler
InformationsquelleAutor iperov
Wenn Sie dieses Skript auf einem linux-basierten Rechner, sollten Sie in der Lage sein:
Würde diese Hilfe: Fügen Sie einen print vor und nach der diese spezielle Funktion. Analysieren Sie die Ausgabe mit einem regex alles zu entfernen, was zwischen den drucken oben Hinzugefügt
InformationsquelleAutor GeneralBecos