Перенаправление stdout на "ничего" в python
у меня есть большой проект, состоящий из достаточно большого количества модулей, каждый из которых печатает что-то на стандартный вывод. Сейчас, когда проект вырос в размерах, больших нет. из print
операторы печати много на std out, который сделал программу значительно медленнее.
Итак, теперь я хочу решить на runtime нужно ли печатать что-либо в stdout. Я не могу вносить изменения в модули, так как их много. (Я знаю, что могу перенаправление stdout в файл, но даже это значительно медленно.)
Итак, мой вопрос заключается в том, как перенаправить stdout ни на что, т. е. как мне сделать print
заявление ничего не делать?
# I want to do something like this.
sys.stdout = None # this obviously will give an error as Nonetype object does not have any write method.
В настоящее время единственная идея у меня есть, чтобы сделать класс, который имеет метод записи (который ничего не делает) и перенаправить stdout на экземпляр этого класса.
class DontPrint(object):
def write(*args): pass
dp = DontPrint()
sys.stdout = dp
есть ли встроенный механизм в Python для этого? Или есть что-то лучше, чем это?
9 ответов:
кросс-платформенный:
import os import sys f = open(os.devnull, 'w') sys.stdout = f
На Windows:
f = open('nul', 'w') sys.stdout = f
На Linux:
f = open('/dev/null', 'w') sys.stdout = f
хороший способ сделать это-создать небольшой контекстный процессор, в который вы обернете свои отпечатки. Вы тогда просто использовать это в
with
-заявление, чтобы заставить замолчать все выходные.import os import sys from contextlib import contextmanager @contextmanager def silence_stdout(): new_target = open(os.devnull, "w") old_target, sys.stdout = sys.stdout, new_target try: yield new_target finally: sys.stdout = old_target with silence_stdout(): print("will not print") print("this will print")
при выполнении этого кода выводится только вторая строка вывода, а не первая:
$ python test.py this will print
это работает кросс-платформенный (Windows + Linux + Mac OSX), и чище, чем те, другие ответы imho.
(по крайней мере, в моей системе) похоже, что запись в ОС.devnull примерно в 5 раз быстрее, чем запись в класс DontPrint, т. е.
#!/usr/bin/python import os import sys import datetime ITER = 10000000 def printlots(out, it, st="abcdefghijklmnopqrstuvwxyz1234567890"): temp = sys.stdout sys.stdout = out i = 0 start_t = datetime.datetime.now() while i < it: print st i = i+1 end_t = datetime.datetime.now() sys.stdout = temp print out, "\n took", end_t - start_t, "for", it, "iterations" class devnull(): def write(*args): pass printlots(open(os.devnull, 'wb'), ITER) printlots(devnull(), ITER)
дало следующий результат:
<open file '/dev/null', mode 'wb' at 0x7f2b747044b0> took 0:00:02.074853 for 10000000 iterations <__main__.devnull instance at 0x7f2b746bae18> took 0:00:09.933056 for 10000000 iterations
Если вы находитесь в среде Unix (включая Linux), вы можете перенаправить вывод на
/dev/null
:python myprogram.py > /dev/null
и для Windows:
python myprogram.py > nul
как насчет этого:
from contextlib import ExitStack, redirect_stdout import os with ExitStack() as stack: if should_hide_output(): null_stream = open(os.devnull, "w") stack.enter_context(null_stream) stack.enter_context(redirect_stdout(null_stream)) noisy_function()
Это использует функции contextlib модуль для скрытия вывода любой команды, которую вы пытаетесь запустить, в зависимости от результата
should_hide_output()
, а затем восстанавливает поведение вывода после выполнения этой функции.если вы хотите скрыть вывод стандартной ошибки, то импортируйте
redirect_stderr
Сcontextlib
и добавить такую строку:stack.enter_context(redirect_stderr(null_stream))
.основной недостаток в том, что это работает только в Python 3.4 и следующие версии.
Если вы находитесь в Python 3.4 или выше, есть простое и безопасное решение с помощью стандартной библиотеки:
import contextlib import os with contextlib.redirect_stdout(None): print("This won't print!")
ваш класс будет работать нормально (за исключением
write()
имя метода -- он должен называтьсяwrite()
, строчные). Просто убедитесь, что вы сохранили копиюsys.stdout
в другой переменной.если вы находитесь на * NIX, вы можете сделать
sys.stdout = open('/dev/null')
, но это менее портативно, чем прокатывать свой собственный класс.
sys.stdout = None
Это нормально
print()
case. Но это может вызвать ошибку, если вы вызываете любой метод sys.поток stdout, например,sys.stdout.write()
.есть обратите внимание, в документах:
при некоторых условиях stdin, stdout и stderr, а также оригинал значения stdin,stdout и stderr не может быть ни одного. Обычно случай для приложений с графическим интерфейсом Windows, которые не подключены к консоли и Приложения Python начались с pythonw.