Stille den stdout einer Funktion in Python ohne Dresch-sys.stdout und wiederherstellen von jedem Funktionsaufruf
Gibt es eine Möglichkeit in Python zu schweigen stdout ohne Umhüllung eine Funktion aufrufen, wie folgende?
Original Gebrochen-Code:
from sys import stdout
from copy import copy
save_stdout = copy(stdout)
stdout = open('trash','w')
foo()
stdout = save_stdout
Edit: Korrigierte code von Alex Martelli
import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout
So funktioniert, scheint aber furchtbar ineffizient. Es hat der bessere Weg zu sein. Irgendwelche Ideen?
Ich würde sagen, Sie sollte es lassen, unkorrigiert, da Alex schon Tat es für Sie. Es würde mehr Sinn machen, ist das Lesen.
Cawas: ich werde meine erste unkorrigierte man wieder oben. Oder etwas ähnliches mit dem gleichen Fehler. Gute Entscheidung,
Verwandte: Vorübergehend Umleiten von stdout/stderr
Cawas: ich werde meine erste unkorrigierte man wieder oben. Oder etwas ähnliches mit dem gleichen Fehler. Gute Entscheidung,
Verwandte: Vorübergehend Umleiten von stdout/stderr
InformationsquelleAutor Tim McJilton | 2010-05-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zuweisung der
stdout
variable, wie Sie tun, hat keinerlei Auswirkungen, vorausgesetztfoo
enthältprint
Aussagen-noch ein weiteres Beispiel, warum Sie sollten nie-import-Sachen aus innen ein Modul (wie du hier tust), aber immer auf ein Modul als ganzes (dann verwenden Sie qualifizierten Namen). Diecopy
ist irrelevant, die durch die Art und Weise. Das korrekte äquivalent zu Ihrem snippet:Jetzt, wenn der code korrekt ist, ist die Zeit, um zu machen es mehr elegant oder schnell. Zum Beispiel könnten Sie verwenden eine in-memory file-like-Objekt anstelle der Datei 'trash':
für Eleganz, ein Kontext am besten ist, e.g:
sobald Sie definiert haben, in diesem Zusammenhang, für jeden block, in dem Sie nicht wollen, eine stdout,
Mehr Optimierung: Sie brauchen nur zu ersetzen, sys.stdout mit einem Objekt, einem no-op
write
Methode. Zum Beispiel:verwendet werden, die gleiche Weise wie die Vorherige Umsetzung von
nostdout
. Ich glaube nicht, dass es etwas sauberer oder schneller als diese;-).Es sollte angemerkt werden, dass, wenn Sie diese in einer Multithread-Umgebung, die Ihre substitution gelten für alle threads. Also, wenn Sie es verwenden in einer Multithread-webserver zum Beispiel, stdout erhalten trashed für alle threads (für die Dauer dieser Funktion rufen, die einige zufällige Teil der Zeit in anderen threads). Die Handhabung dieser Falle ist schwer, und würde
threading.local
(vor allem ich würde empfehlen, versuchen Sie zu vermeiden threads und stdout-Umleitung).Ich habe downvoted weil dies macht code hängen — in einer Weise, dass es nicht unterbrochen werden kann, soweit ich das beurteilen kann—, wenn eine Ausnahme ausgelöst wird, im Kontext. Ich denke, @bitmous Antwort robuster und mehr elegant in sehr geschickter Weise (ohne die Notwendigkeit für die
DummyFile
Klasse).Nachdem keine Antworten in diesem thread für mich gearbeitet, ich fand heraus, nach Art zu lang, dass eine C-level-Funktion zum generieren der Ausgabe, die der python-stdout nicht fangen direkt an. Die folgende Antwort hat geholfen: stackoverflow.com/a/17954769/2965879 insbesondere
sys.stdout.close()
imtry
-block sollte helfen.InformationsquelleAutor Alex Martelli
Nur hinzufügen, was andere schon gesagt, Python 3.4 eingeführt, die
contextlib.redirect_stdout
Kontext-manager. Es akzeptiert eine Datei(-like) Objekt, auf das die Ausgabe umgelenkt.Umleiten zu /dev/null unterdrückt die Ausgabe:
Diese Lösung angepasst werden kann verwendet werden als Dekorateur:
Andere mögliche und gelegentlich nützliche Lösung, die die Arbeit in beiden Python 2 und 3 ist das bestehen /dev/null als argument zu
f
und leiten Sie die Ausgabe über diefile
argument derprint
Funktion:Können Sie auch
target
komplett optional:Beachten Sie, müssen Sie
in Python 2.
InformationsquelleAutor vaultah
Warum glaubst du, ist das ineffizient? Hast du test? Übrigens, es funktioniert nicht bei allen, weil Sie die
from ... import
- Anweisung.Ersetzen
sys.stdout
ist gut, aber nicht machen Sie eine Kopie und verwenden Sie nicht eine temporäre Datei. Öffnen Sie das null-Gerät statt:Es sollte
open(os.devnull, 'w')
. Im Allgemeinenos.devnull
ist nützlich, wenn Sie echte Datei-Objekt. Aberprint
akzeptiert alles, was mit einemwrite()
Methode.+1 für das os.devnull.. überrascht die Gewinner Antwort propagierte die Verwendung von Dateien für die Ausgabe.
In der Tat sollte es
open(os.devnull, 'w')
. Ansonsten bekommen Sie:[Errno 9] Bad file descriptorInformationsquelleAutor Philipp
Geläute in sehr spät, um dies mit dem, was ich dachte, war eine saubere Lösung für dieses problem.
Verwendung:
self
als trivialwrite
r ist sehr clever.Dies ist sicherlich die beste Antwort. Tipp für alle die unsicher sind: wenn Sie wollen, dass Fehler geworfen werden, als normal, ersetzen Sie einfach
# Do normal exception handling
mitraise
. Ich habe ein editEs sollte auch erwähnt werden, hier, dass, wenn Sie irgendwelche debugger Spuren legen in
DoMyFunction()
werden, werden Sie unsichtbar, das Programm einfach warten, auf die Spur, mit keine Aufforderung.Was meinst du normale exception handling hier? Was genau wird diese zu fangen? Wenn ich dies nutzen wollen, für eine beliebige Anzahl von abstrakten Fällen, was sollte ich erwarten, zu schlagen
if type is not None
und was passiert, wenn ich das weglasse?InformationsquelleAutor bitmous
Leicht ändern Alex Martelli Antwort...
Diese Adressen dem Fall, wo Sie immer wollen zu unterdrücken
stdout
für eine Funktion anstelle von einzelnen Aufrufe der Funktion.Wenn
foo()
wurde viele Male aufgerufen würde es möglicherweise besser/einfacher zu wickeln, die Funktion (dekorieren). Auf diese Weise ändern Sie die definition vonfoo
einmal statt encasing jeder Verwendung der Funktion in einer with-Anweisung.Tim: Es ist größte Vorteil ist, speichern Programmierer Zeit durch die Verringerung der Anzahl von änderungen, die Sie vornehmen müssen, um Ihren code zu deaktivieren stdout für eine Funktion. Ich habe keine performance-test gegen den contextmanager noch.
tgray: Das ist, was ich dachte. Es ist eine gute Idee, obwohl. Ich mag es. Ich denke, beide Ansätze sind gut, je nachdem, was Sie versuchen zu tun. DH, wenn Sie versuchen, zu ersetzen, eine call-in 100s der Ort, die Art und Weise ist besser, aber wenn Sie wollen, um es für eine Funktion übergeben in eine andere Funktion, ich denke, den anderen hat seine Vorteile. Ich mag es wenn
tgray: Random Hinweis. Nach timing der zwei Wege Verpackung eine Funktion, die nicht einfach 1+1, weil ich nur ein Auge an den Gemeinkosten. That being said, es war ziemlich viel waschen. Also, was jemals zwischen den beiden Stilen ist am einfachsten zu implementieren, ist das one to go für.
InformationsquelleAutor tgray
Durch Generalisierung noch mehr, können Sie eine schöne Dekorateur, die Erfassung der Ausgabe und auch die Rücksendung:
InformationsquelleAutor e-satis
Ich glaube nicht, dass es etwas sauberer oder schneller als diese;-)
Bah! Ich glaube, ich kann ein wenig besser 😀
Dem bekommt, was wollte ich ursprünglich, um die Ausgabe unterdrücken aber normalerweise zeigen die Unterdrückten ausgegeben, wenn ein Fehler ausgegeben wurde.
InformationsquelleAutor PatB
redirect_stdout() Hinzugefügt wurde contextlib da python 3.4
Python >= 3.4, dies sollte es tun:
InformationsquelleAutor Pin-Yen