Suprimir llamadas para imprimir (python)

¿Hay alguna manera de evitar que una función llame a print ?


Estoy usando el módulo pygame.joystick para un juego en el que estoy trabajando.

pygame.joystick.Joystick un objeto pygame.joystick.Joystick y en el bucle real del juego, llame 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 el juego considerablemente.

¿Puedo bloquear esta llamada para print ?

Related of "Suprimir llamadas para imprimir (python)"

Python le permite sobrescribir la salida estándar (stdout) con cualquier objeto de archivo. Esto debería funcionar multiplataforma y escribir en el dispositivo nulo.

 import sys, os # Disable def blockPrint(): sys.stdout = open(os.devnull, 'w') # Restore def enablePrint(): sys.stdout = sys.__stdout__ print 'This will print' blockPrint() print "This won't" enablePrint() print "This will too" 

Si no desea que se imprima esa función, llame a blockPrint() antes de ella, y enablePrint() cuando desee que continúe. Si desea desactivar toda la impresión, comience a bloquear en la parte superior del archivo.

Sobre la base de 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 se puede olvidar volver a habilitar la salida estándar, lo cual es especialmente importante cuando se manejan excepciones.

 # This is an example of not-so-good solution # without 'with' context manager statement. try: disable_prints() something_throwing() # enable_prints() This wouldn't be enough! except ValueError: handle_error() finally: enable_prints() # That's where it needs to go. 

Si olvidó la cláusula finally , ninguna de sus llamadas impresas imprimirá nada más. Usando el enunciado with , eso no puede suceder.

No es seguro usar sys.stdout = None , porque alguien podría llamar a métodos como sys.stdout.write ()

No, no hay, especialmente que la mayoría de PyGame está escrito en C.

Pero si esta función llama a imprimir, entonces se trata de un error de PyGame, y deberías informarlo.

He tenido el mismo problema, y ​​no llegué a otra solución sino a redirigir la salida del progtwig (no sé exactamente si el spamming ocurre en stdout o stderr) a /dev/null nirvana.

De hecho, es de código abierto, pero no era lo suficientemente apasionado como para sumergirme en las fonts de pygame , y el proceso de comstackción, para detener de alguna manera el spam de depuración.

EDITAR:

El módulo pygame.joystick tiene llamadas a printf en todas las funciones que devuelven los valores reales a Python:

 printf("SDL_JoystickGetButton value:%d:\n", value); 

Desafortunadamente, deberías comentarlos y recomstackr todo el asunto. Tal vez el setup.py proporcionado haría esto más fácil de lo que pensaba. Podrías probar esto …

Un enfoque completamente diferente sería redirigir en la línea de comando. Si estás en Windows, esto significa un script por lotes. En Linux, bash.

 /full/path/to/my/game/game.py > /dev/null C:\Full\Path\To\My\Game.exe > nul 

A menos que estés tratando con múltiples procesos, esto debería funcionar. Para los usuarios de Windows, estos podrían ser los accesos directos que está creando (menú de inicio / escritorio).

El módulo que utilicé imprimió a stderr . Así que la solución en ese caso sería:

 sys.stdout = open(os.devnull, 'w') 

Como sugirió @Alexander Chzhen, usar un administrador de contexto sería más seguro que llamar a un par de funciones que cambian de estado.

Sin embargo, no es necesario que vuelva a implementar el administrador de contexto, ya está en la biblioteca estándar. Puede redireccionar stdout (el objeto de archivo que se usa para print ) con contextlib.redirect_stdout , y también stderr con contextlib.redirect_stderr .

 import os import contextlib with open(os.devnull, "w") as f, contextlib.redirect_stdout(f): print("This won't be printed.") 

Si desea bloquear las llamadas de impresión realizadas por una función en particular, hay una solución más limpia con decoradores. Define 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 simplemente coloca @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()