Gibt es eine Möglichkeit, den Aufruf einer Funktion zu stoppen print
?
Ich benutze das pygame.joystick
Modul für ein Spiel, an dem ich arbeite.
Ich habe ein pygame.joystick.Joystick
Objekt erstellt und in der eigentlichen Schleife des Spiels seine Mitgliedsfunktion aufgerufen get_button
, um nach Benutzereingaben zu suchen. Die Funktion macht alles, was ich brauche, aber das Problem ist, dass sie auch aufruft print
, was das Spiel erheblich verlangsamt.
Kann ich diesen Anruf blockierenprint
?
Basierend auf der @ FakeRainBrigand-Lösung schlage ich eine sicherere Lösung vor:
import os, sys class HiddenPrints: def __enter__(self): self._original_stdout = sys.stdout sys.stdout = open(os.devnull, 'w') def __exit__(self, exc_type, exc_val, exc_tb): sys.stdout.close() sys.stdout = self._original_stdout
Dann können Sie es so verwenden:
with HiddenPrints(): print("This will not be printed") print("This will be printed as before")
Dies ist viel sicherer, da Sie nicht vergessen können, stdout wieder zu aktivieren, was besonders wichtig ist, wenn Sie Ausnahmen behandeln.
Ohne
with
Im folgenden Beispiel werden Druckfunktionen zum Aktivieren / Deaktivieren verwendet, die in der vorherigen Antwort vorgeschlagen wurden.
Stellen Sie sich vor, es gibt einen Code, der eine Ausnahme auslösen kann. Wir mussten
finally
Anweisung verwenden, um Drucke auf jeden Fall zu ermöglichen.try: disable_prints() something_throwing() enable_prints() # This will not help in case of exception except ValueError as err: handle_error(err) finally: enable_prints() # That's where it needs to go.
Wenn Sie die
finally
Klausel vergessen haben , würde keiner Ihrerprint
Anrufe mehr drucken.Es ist
with
sicherer, die Anweisung zu verwenden, die sicherstellt, dass die Ausdrucke wieder aktiviert werden.Hinweis: Die Verwendung ist nicht sicher
sys.stdout = None
, da jemand Methoden wie aufrufen könntesys.stdout.write()
quelle
ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='w' encoding='UTF-8'>
bei der Verwendung dieses Codes, löste es durch Setzen von sys.stdout = None anstelle von open (os.devnull, 'w')sys.stdout.close()
die Exit-Methode hinzugefügt . Das sollte helfen. Beachten Sie,sys.stdout = None
dass dies einen Fehler verursachen kann, da jemand die Methoden von stdout wie aufrufen kannsys.stdout.write()
.Wie @Alexander Chzhen vorschlug, wäre die Verwendung eines Kontextmanagers sicherer als das Aufrufen eines Paares von Statusänderungsfunktionen.
Sie müssen den Kontextmanager jedoch nicht erneut implementieren - er befindet sich bereits in der Standardbibliothek. Sie können mit und auch mit umleiten
stdout
(dasprint
verwendete Dateiobjekt) .contextlib.redirect_stdout
stderr
contextlib.redirect_stderr
import os import contextlib with open(os.devnull, "w") as f, contextlib.redirect_stdout(f): print("This won't be printed.")
quelle
Wenn Sie Druckaufrufe einer bestimmten Funktion blockieren möchten, gibt es eine übersichtlichere Lösung mit Dekoratoren. Definieren Sie den folgenden Dekorateur:
# decorater used to block function printing to the console def blockPrinting(func): def func_wrapper(*args, **kwargs): # block all printing to the console sys.stdout = open(os.devnull, 'w') # call the method in question value = func(*args, **kwargs) # enable all printing to the console sys.stdout = sys.__stdout__ # pass the return value of the method back return value return func_wrapper
Dann einfach
@blockPrinting
vor jede Funktion stellen. Zum Beispiel:# This will print def helloWorld(): print("Hello World!") helloWorld() # This will not print @blockPrinting def helloWorld2(): print("Hello World!") helloWorld2()
quelle
Nein, das gibt es nicht, insbesondere, dass die Mehrheit von PyGame in C geschrieben ist.
Wenn diese Funktion print aufruft, liegt ein PyGame-Fehler vor, und Sie sollten ihn nur melden.
quelle
Ich hatte das gleiche Problem und bin nicht zu einer anderen Lösung gekommen, sondern um die Ausgabe des Programms (ich weiß nicht genau, ob das Spam auf stdout oder stderr stattfindet) auf
/dev/null
Nirvana umzuleiten .In der Tat ist es Open Source, aber ich war nicht leidenschaftlich genug, um in die
pygame
Quellen - und den Erstellungsprozess - einzutauchen, um den Debug-Spam irgendwie zu stoppen.EDIT:
Das
pygame.joystick
Modul hat Aufrufeprintf
in allen Funktionen, die die tatsächlichen Werte an Python zurückgeben:printf("SDL_JoystickGetButton value:%d:\n", value);
Leider müssten Sie diese auskommentieren und das Ganze neu kompilieren. Vielleicht
setup.py
würde das zur Verfügung gestellte dies einfacher machen als ich dachte. Sie könnten dies versuchen ...quelle
Ein völlig anderer Ansatz wäre die Umleitung über die Befehlszeile. Wenn Sie unter Windows arbeiten, bedeutet dies ein Batch-Skript. Unter Linux Bash.
Dies sollte funktionieren , es sei denn, Sie haben es mit mehreren Prozessen zu tun . Für Windows-Benutzer können dies die Verknüpfungen sein, die Sie erstellen (Startmenü / Desktop).
quelle
Das Modul, mit dem ich gedruckt habe
stderr
. Die Lösung in diesem Fall wäre also:sys.stdout = open(os.devnull, 'w')
quelle
Basierend auf der @ Alexander Chzhen-Lösung präsentiere ich hier die Möglichkeit, sie auf eine Funktion anzuwenden, mit der Option, das Drucken zu unterdrücken oder nicht.
import os, sys class SuppressPrints: #different from Alexander`s answer def __init__(self, suppress=True): self.suppress = suppress def __enter__(self): if self.suppress: self._original_stdout = sys.stdout sys.stdout = open(os.devnull, 'w') def __exit__(self, exc_type, exc_val, exc_tb): if self.suppress: sys.stdout.close() sys.stdout = self._original_stdout #implementation def foo(suppress=True): with SuppressPrints(suppress): print("It will be printed, or not") foo(True) #it will not be printed foo(False) #it will be printed
Ich hoffe, ich kann meine Lösung unter der Antwort von Alexander als Kommentar hinzufügen, aber ich habe nicht genug (50) Ruf, um dies zu tun.
quelle
Sie können eine einfache Umleitung durchführen. Dies scheint viel sicherer zu sein, als mit stdout herumzuspielen, und zieht keine zusätzlichen Bibliotheken ein.
enable_print = print disable_print = lambda *x, **y: None print = disable_print function_that_has_print_in_it(1) # nothing is printed print = enable_print function_that_has_print_in_it(2) # printing works again!
Hinweis: Dies funktioniert nur zum Deaktivieren der Funktion print () und würde nicht die gesamte Ausgabe deaktivieren, wenn Sie etwas anderes aufrufen, das eine Ausgabe erzeugt. Zum Beispiel, wenn Sie eine C-Bibliothek aufgerufen haben, die ihre eigene Ausgabe an stdout erstellt hat, oder wenn Sie intput () verwendet haben.
quelle