I'm using Pygame/SDL's joystick module to get input from a gamepad. Every time I call its get_hat() method it prints to the console. This is problematic since I use the console to help me debug and now it gets flooded with SDL_JoystickGetHat value:0: 60 times every second. Is there a way I can disable this? Either through an option in Pygame/SDL or suppress console output while the function calls? I s开发者_运维知识库aw no mention of this in the Pygame documentation.
edit: This turns out to be due to debugging being turned on when the SDL library was compiled.
Just for completeness, here's a nice solution from Dave Smith's blog:
from contextlib import contextmanager
import sys, os
@contextmanager
def suppress_stdout():
with open(os.devnull, "w") as devnull:
old_stdout = sys.stdout
sys.stdout = devnull
try:
yield
finally:
sys.stdout = old_stdout
With this, you can use context management wherever you want to suppress output:
print("Now you see it")
with suppress_stdout():
print("Now you don't")
To complete charles's answer, there are two context managers built in to python, redirect_stdout and redirect_stderr which you can use to redirect and or suppress a commands output to a file or StringIO variable.
import contextlib
with contextlib.redirect_stdout(None):
do_thing()
For a more complete explanation read the docs
A quick update: In some cases passing None might raise some reference errors (e.g. keras.models.Model.fit calls sys.stdout.write which will be problematic), in that case pass an io.StringIO() or os.devnull.
You can get around this by assigning the standard out/error (I don't know which one it's going to) to the null device. In Python, the standard out/error files are sys.stdout/sys.stderr, and the null device is os.devnull, so you do
sys.stdout = open(os.devnull, "w")
sys.stderr = open(os.devnull, "w")
This should disable these error messages completely. Unfortunately, this will also disable all console output. To get around this, disable output right before calling the get_hat() the method, and then restore it by doing
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
which restores standard out and error to their original value.
Here's the relevant block of code from joystick.c (via SVN at http://svn.seul.org/viewcvs/viewvc.cgi/trunk/src/joystick.c?view=markup&revision=2652&root=PyGame)
value = SDL_JoystickGetHat (joy, _index);
#ifdef DEBUG
printf("SDL_JoystickGetHat value:%d:\n", value);
#endif
if (value & SDL_HAT_UP) {
Looks like a problem with having debugging turned on.
Building on @charleslparker's answer:
from contextlib import contextmanager
import sys, os
@contextmanager
def suppress_stdout():
with open(os.devnull, "w") as devnull:
old_stdout = sys.stdout
sys.stdout = devnull
try:
yield
finally:
sys.stdout = old_stdout
print("Now you see it")
with suppress_stdout():
print("Now you don't")
Tests
>>> with suppress_stdout():
os.system('play /mnt/Vancouver/programming/scripts/PHASER.WAV')
/mnt/Vancouver/programming/scripts/PHASER.WAV:
File Size: 1.84k Bit Rate: 90.4k
Encoding: Unsigned PCM
Channels: 1 @ 8-bit
Samplerate: 11025Hz
Replaygain: off
Duration: 00:00:00.16
In:100% 00:00:00.16 [00:00:00.00] Out:1.79k [!=====|=====!] Clip:0
Done.
Use this to completely suppress os.system() output:
>>> with suppress_stdout():
os.system('play /mnt/Vancouver/programming/scripts/PHASER.WAV >/dev/null 2>&1')
>>> ## successfully executed
>>> import time
>>> with suppress_stdout():
for i in range(3):
os.system('play /mnt/Vancouver/programming/scripts/PHASER.WAV >/dev/null 2>&1')
time.sleep(0.5)
>>> ## successfully executed
Useful (e.g.) to signal completion of long-running scripts.
I use pythonw.exe (on Windows) instead of python.exe. In other OSes, you could also redirect output to /dev/nul. And in order to still see my debug output, I am using the logging module.
As Demolishun mentions in an answer to a closed duplicate question, there is a thread talking about this issue. The thread is from August of 2009 and one of the developers says the debug code was left in on accident. I had installed Pygame 1.9.1 from pip and the debug output is still present.
To get around it for now, I downloaded the source from pygame.org, removed the print statements from src/joystick.c and compiled the code.
I am on OS X 10.7.5 for what it's worth.
If you are on a Debian or Ubuntu machine you can just simply recompile pygame without the messages.
cd /tmp
sudo apt-get build-dep pygame
apt-get source pygame
vim pygame-1.9.1release+dfsg/src/joystick.c
# search for the printf("SDL.. messages and put a // in front
apt-get source --compile pygame
sudo dpkg -i python-pygame_1.9.1release+dfsg-9ubuntu1_amd64.deb
Greetings Max
加载中,请稍侯......
精彩评论