开发者

How to suppress console output in Python?

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜