如何在Python中抑制控制台输出?

时间:2010-01-24 02:44:00

标签: python sdl pygame

我正在使用Pygame / SDL的操纵杆模块从游戏手柄获取输入。每当我调用它的get_hat()方法时,它就会打印到控制台。这是有问题的,因为我使用控制台来帮助我调试,现在它每秒被SDL_JoystickGetHat value:0:充斥60次。有没有办法可以禁用它?通过Pygame / SDL中的选项或在函数调用时抑制控制台输出?我在Pygame文档中没有提到这一点。

编辑:原因是在编译SDL库时打开了调试功能。

8 个答案:

答案 0 :(得分:27)

为了完整起见,这是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

有了这个,您可以在任何想要抑制输出的地方使用上下文管理:

print("Now you see it")
with suppress_stdout():
    print("Now you don't")

答案 1 :(得分:11)

你可以通过将标准输出/错误(我不知道它将去哪一个)分配给空设备来解决这个问题。在Python中,标准输出/错误文件为sys.stdout / sys.stderr,空设备为os.devnull,因此您可以

sys.stdout = open(os.devnull, "w")
sys.stderr = open(os.devnull, "w")

这应该完全禁用这些错误消息。不幸的是,这也将禁用所有控制台输出。要解决此问题,请在调用get_hat()方法之前禁用输出,然后通过执行

来恢复它
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__

将标准输出和错误恢复为原始值。

答案 2 :(得分:7)

要完成查尔斯的回答,有两个内置于python,redirect_stdoutredirect_stderr的上下文管理器,您可以使用这些管理器重定向或抑制输出到文件的命令或{ {1}}变量。

StringIO

有关更完整的说明,请阅读the docs

答案 3 :(得分:4)

以下是来自joystick.c的相关代码块(通过SVN 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) {

看起来打开调试时出现问题。

答案 4 :(得分:1)

我使用pythonw.exe(在Windows上)而不是python.exe。 在其他操作系统中,您还可以将输出重定向到/ dev / nul。 为了仍然看到我的调试输出,我正在使用日志记录模块。

答案 5 :(得分:1)

由于Demolishunanswer中提到了一个封闭的重复问题,因此thread正在讨论此问题。该主题是从2009年8月开始的,其中一位开发人员说the debug code was left in on accident。我从pip安装了Pygame 1.9.1,调试输出仍然存在。

为了解决这个问题,我从pygame.org下载了源代码,从src / joystick.c中删除了print语句并编译了代码。

我在OS X 10.7.5上了解它的价值。

答案 6 :(得分:1)

基于@charleslparker的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")

测试

>>> 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.

使用此命令完全禁止显示os.system()输出:

>>> 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

有用(例如)表示长时间运行的脚本已完成。

答案 7 :(得分:0)

如果你使用的是Debian或Ubuntu机器,你只需重新编译没有消息的pygame。

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

问候 最大