¿Hay alguna forma de evitar que una función llame print
?
Estoy usando el pygame.joystick
módulo para un juego en el que estoy trabajando.
Creé un pygame.joystick.Joystick
objeto y en el bucle real del juego llamé a su función miembro get_button
para verificar la entrada del usuario. La función hace todo lo que necesito que haga, pero el problema es que también llama print
, lo que ralentiza considerablemente el juego.
¿Puedo bloquear esta llamada a print
?
Basado en la solución @FakeRainBrigand, sugiero una solución más segura:
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
Entonces puedes usarlo así:
with HiddenPrints(): print("This will not be printed") print("This will be printed as before")
Esto es mucho más seguro porque no puede olvidarse de volver a habilitar stdout, que es especialmente crítico cuando se manejan excepciones.
Sin
with
El siguiente ejemplo usa las funciones de habilitar / deshabilitar impresiones que se sugirieron en la respuesta anterior.
Imagine que hay un código que puede generar una excepción. Tuvimos que usar
finally
declaración para habilitar impresiones en cualquier caso.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.
Si olvidó la
finally
cláusula, ninguna de susprint
llamadas imprimiría nada más.Es más seguro usar la
with
instrucción, que asegura que las impresiones se volverán a habilitar.Nota: No es seguro de usar
sys.stdout = None
, porque alguien podría llamar a métodos comosys.stdout.write()
fuente
ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='w' encoding='UTF-8'>
al usar este código, lo resolví configurando sys.stdout = None en lugar de open (os.devnull, 'w')sys.stdout.close()
al método de salida. Esto debería ayudar. Tenga en cuenta quesys.stdout = None
puede causar un error, porque alguien puede llamar a los métodos de stdout comosys.stdout.write()
.Como sugirió @Alexander Chzhen, usar un administrador de contexto sería más seguro que llamar a un par de funciones de cambio de estado.
Sin embargo, no es necesario volver a implementar el administrador de contexto; ya está en la biblioteca estándar. Puede redirigir
stdout
(el objeto de archivo queprint
utiliza) concontextlib.redirect_stdout
, y tambiénstderr
concontextlib.redirect_stderr
.import os import contextlib with open(os.devnull, "w") as f, contextlib.redirect_stdout(f): print("This won't be printed.")
fuente
Si desea bloquear las llamadas de impresión realizadas por una función en particular, existe una solución más ordenada utilizando decoradores. Defina el siguiente decorador:
# 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
Luego, colóquelo
@blockPrinting
antes de cualquier función. Por ejemplo:# This will print def helloWorld(): print("Hello World!") helloWorld() # This will not print @blockPrinting def helloWorld2(): print("Hello World!") helloWorld2()
fuente
No, no lo hay, especialmente porque la mayoría de PyGame está escrito en C.
Pero si esta función llama a print, entonces es un error de PyGame, y debería informarlo.
fuente
Tuve el mismo problema y no encontré otra solución que la de redirigir la salida del programa (no sé exactamente si el spam ocurre en stdout o stderr) al
/dev/null
nirvana.De hecho, es de código abierto, pero no me apasionó lo suficiente como para sumergirme en las
pygame
fuentes, y el proceso de compilación, para detener de alguna manera el spam de depuración.EDITAR:
El
pygame.joystick
módulo tiene llamadas aprintf
en todas las funciones que devuelven los valores reales a Python:printf("SDL_JoystickGetButton value:%d:\n", value);
Desafortunadamente, tendría que comentarlos y volver a compilar todo. Quizás lo provisto
setup.py
haría esto más fácil de lo que pensaba. Podrías probar esto ...fuente
Un enfoque completamente diferente sería redirigir en la línea de comando. Si está en Windows, esto significa un script por lotes. En Linux, bash.
A menos que esté tratando con varios procesos, esto debería funcionar. Para los usuarios de Windows, estos podrían ser los accesos directos que está creando (menú de inicio / escritorio).
fuente
El módulo que usé imprimió
stderr
. Entonces la solución en ese caso sería:sys.stdout = open(os.devnull, 'w')
fuente
Basado en la solución @Alexander Chzhen, presento aquí la forma de aplicarlo en una función con una opción para suprimir la impresión o no.
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
Espero poder agregar mi solución debajo de la respuesta de Alexander como comentario, pero no tengo suficientes (50) reputaciones para hacerlo.
fuente
Puede hacer una redirección simple, esto parece mucho más seguro que jugar con stdout y no incluye bibliotecas adicionales.
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!
Nota: esto solo funciona para deshabilitar la función print () y no deshabilitaría toda la salida si está haciendo llamadas a otra cosa que está produciendo salida. Por ejemplo, si estaba llamando a una biblioteca C que estaba produciendo su propia salida a stdout, o si estaba usando intput ().
fuente