Как подавить вывод консоли в Python?
Я использую модуль джойстика Pygame/SDL для получения ввода с геймпада. Каждый раз звоню get_hat()
метод это печатает на консоль. Это проблематично, так как я использую консоль, чтобы помочь мне отладить, и теперь она затопляется SDL_JoystickGetHat value:0:
60 раз каждую секунду. Есть ли способ, которым я могу отключить это? Либо через опцию в Pygame/SDL, либо запретить вывод на консоль при вызове функции? Я не видел упоминаний об этом в документации Pygame.
edit: Это происходит из-за того, что отладка была включена, когда библиотека SDL была скомпилирована.
9 ответов
Вот соответствующий блок кода из 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) {
Похоже, проблема с включенной отладкой.
Просто для полноты, вот хорошее решение из блога Дэйва Смита:
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()
Для более полного объяснения прочитайте документы
Вы можете обойти это, назначив стандартное out/error (я не знаю, к какому типу это относится) нулевому устройству. В Python стандартные файлы out / error sys.stdout
/sys.stderr
и нулевое устройство os.devnull
так ты делаешь
sys.stdout = os.devnull
sys.stderr = os.devnull
Это должно полностью отключить эти сообщения об ошибках. К сожалению, это также отключит весь вывод консоли. Чтобы обойти это, отключите вывод прямо перед вызовом get_hat()
метод, а затем восстановить его, выполнив
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
который восстанавливает стандартные ошибки и ошибки до их первоначального значения.
Основываясь на @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
Полезно (например), чтобы сигнализировать о завершении длительных сценариев.
Я использую pythonw.exe (в Windows) вместо python.exe. В других ОС вы также можете перенаправить вывод в /dev/nul. И для того, чтобы все еще видеть мои выходные данные отладки, я использую модуль регистрации.
Как упоминает Demolishun в ответе на закрытый дубликат вопроса, об этой проблеме есть тема. Этот поток относится к августу 2009 года, и один из разработчиков говорит, что отладочный код был оставлен случайно. Я установил Pygame 1.9.1 из pip, и выходные данные отладки все еще присутствуют.
Чтобы обойти это сейчас, я скачал исходник с 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
Привет Макс
Решения с использованиемos.devnull
может вызвать проблемы синхронизации с многопроцессорной обработкой, поэтому несколько процессов будут ожидать одного и того же ресурса. По крайней мере, это то, с чем я столкнулся в Windows.
Следующее решение может быть лучше:
class DummyOutput(object):
def __init__(self, *args, **kwargs):
pass
def write(self, *args, **kwargs):
pass
class suppress_stdout_stderr(object):
def __init__(self):
self.stdout = sys.stdout
self.stderr = sys.stderr
def __enter__(self, *args, **kwargs):
out = DummyOutput()
sys.stdout = out
sys.stderr = out
def __exit__(self, *args, **kwargs):
sys.stdout = self.stdout
sys.stderr = self.stderr
with suppress_stdout_stderr():
print(123, file=sys.stdout)
print(123, file=sys.stderr)