我正在使用 Pygame/SDL 的操纵杆模块从游戏手柄获取输入。每次我调用它的get_hat()
方法时,它都会打印到控制台。这是有问题的,因为我使用控制台来帮助我调试,现在它SDL_JoystickGetHat value:0:
每秒被淹没 60 次。有没有办法可以禁用它?通过 Pygame/SDL 中的选项或在函数调用时抑制控制台输出?我在 Pygame 文档中没有看到任何提及。
编辑:这原来是由于在编译 SDL 库时打开了调试。
为了完整起见,这里有一个来自Dave Smith 博客的不错的解决方案:
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")
为了完成查尔斯的回答,python 内置了两个上下文管理器redirect_stdout
,redirect_stderr
您可以使用它们来重定向和/或抑制命令输出到文件或StringIO
变量。
import contextlib
with contextlib.redirect_stdout(None):
do_thing()
有关更完整的解释,请阅读文档
快速更新:在某些情况下,传递None
可能会引发一些引用错误(例如会出现问题的keras.models.Model.fit
调用),在这种情况下传递一个or 。sys.stdout.write
io.StringIO()
os.devnull
您可以通过将标准输出/错误(我不知道会发生哪一个)分配给空设备来解决此问题。在 Python 中,标准输出/错误文件是sys.stdout
/ sys.stderr
,而 null 设备是os.devnull
,所以你这样做
sys.stdout = open(os.devnull, "w")
sys.stderr = open(os.devnull, "w")
这应该完全禁用这些错误消息。不幸的是,这也会禁用所有控制台输出。为了解决这个问题,在调用get_hat()
方法之前禁用输出,然后通过执行来恢复它
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
它将标准输出和错误恢复为其原始值。
这是来自 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) {
打开调试似乎有问题。
我使用 pythonw.exe(在 Windows 上)而不是 python.exe。在其他操作系统中,您还可以将输出重定向到 /dev/nul。为了仍然看到我的调试输出,我正在使用日志记录模块。
基于@charleslparker 的回答:
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
有用(例如)表示长时间运行脚本的完成。
正如Demolishun在对已关闭的重复问题的回答中提到的那样,有一个线程在谈论这个问题。该线程是从 2009 年 8 月开始的,其中一位开发人员说调试代码是意外留下的。我已经从 pip 安装了 Pygame 1.9.1 并且调试输出仍然存在。
为了暂时解决这个问题,我从 pygame.org 下载了源代码,从 src/joystick.c 中删除了打印语句并编译了代码。
我在 OS X 10.7.5 上物有所值。
如果你在 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
问候马克斯