2010-01-24 2107 views
19

我使用Pygame/SDL的遊戲杆模塊從遊戲板獲取輸入。每次我打電話給它的get_hat()方法時,它都會打印到控制檯上。這是有問題的,因爲我使用控制檯來幫助我進行調試,現在它每秒鐘都會被淹沒SDL_JoystickGetHat value:0: 60次。有沒有一種方法可以禁用此功能?通過Pygame/SDL中的選項,或者在函數調用時抑制控制檯輸出?我在Pygame文檔中沒有看到這一點。如何在Python中禁止控制檯輸出?

編輯:原來,這是由於在編譯SDL庫時調試打開所致。

+0

現在我很好奇的平臺使用的是(Linux發行版?),你使用的是什麼包?還是你自己編譯它? – Keith 2011-03-12 01:42:50

+0

這是很久以前,但我使用的是Windows,Python 2.6和Pygame 1.9(包括SDL)。我剛剛走了他們的Windows安裝程序,一切都已經編譯完成。 – tankadillo 2011-03-12 18:38:33

回答

3

下面是從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) { 

看起來與具有調試導通的問題。

+0

如何禁用SDL調試雖然Python? Google告訴我環境變量是'SDL_DEBUG',但是插入'os.environ ['SDL_DEBUG'] ='0''似乎沒有效果。 – tankadillo 2010-01-24 04:08:55

+4

@jackson這是SDL的編譯時調試選項。該消息正在打印,因爲在編譯SDL庫時,已定義了DEBUG符號。 – 2010-01-24 04:16:05

+0

啊,好的。謝謝您的幫助! – tankadillo 2010-01-24 04:21:08

10

你可以通過分配標準輸出/錯誤(我不知道它會去哪個)到空設備來解決這個問題。在Python中,標準輸出/錯誤文件sys.stdout/sys.stderr,而空設備os.devnull,所以你做

sys.stdout = os.devnull 
sys.stderr = os.devnull 

這應該完全禁止這些錯誤消息。不幸的是,這也會禁用所有的控制檯輸出。爲了解決這個問題,正確調用get_hat()方法之前禁止輸出,然後通過做

sys.stdout = sys.__stdout__ 
sys.stderr = sys.__stderr__ 

其恢復標準輸出和錯誤的原始值恢復。

+0

我之前沒有意識到這種技術。它似乎是我想要的,但是當我嘗試使用它時,get_hat()函數繼續向控制檯打印。這可能是SDL的問題嗎? – tankadillo 2010-01-24 03:48:07

+1

使用原始sys.stdout和sys.stderr的佔位符在恢復標準輸出時使用將擴展此解決方案,以便在已經存在'非標準'stdout並需要在抑制後保留的情況下工作。例如用於QGIS python控制檯。 – 2014-07-21 06:02:34

+1

第一位工作,但即使是'恢復'位的代碼我仍然沒有得到任何控制檯輸出後? 我在Ubuntu 14.04 3.4.3 – ashgetstazered 2016-03-22 02:53:06

1

我使用pythonw.exe(在Windows上)而不是python.exe。 在其他操作系統中,您也可以將輸出重定向到/ dev/nul。 並且爲了仍然看到我的調試輸出,我正在使用日誌記錄模塊。

1

由於Demolishun提到answer到一個封閉的重複問題,有一個thread談論這個問題。該主題是從2009年8月開始,其中一位開發人員說the debug code was left in on accident。我從pip安裝了Pygame 1.9.1,調試輸出仍然存在。

現在爲了解決它,我從pygame.org下載了源代碼,從src/joystick.c中刪除了打印語句並編譯了代碼。

我在OS X 10.7.5上是值得的。

17

只是爲了完整性,這裏是從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") 
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 

問候 最大

2

要完成查爾斯的答案,有內置在蟒蛇,redirect_stdoutredirect_stderr您可以使用重定向和或抑制命令輸出到文件或StringIO可變兩次上下文經理。

import contextlib 

with contextlib.redirect_stdout(None): 
    do_thing() 

更完整的解釋閱讀the docs

+1

感謝您的提示。您還可以在redirect_stdout()中添加一個打印語句作爲參數。 '用redirect_stdout(print('Worked!')):do_thing()' – myidealab 2017-09-27 16:42:14