在python中将stdoutredirect到“nothing”
我有一个大型的项目,其中包含足够多的模块,每个模块都打印一些标准输出。 现在随着项目的规模不断扩大, 的print
语句打印了很多,使得程序相当慢。
所以,我现在想在运行时决定是否打印任何东西到标准输出。 我不能在模块中进行更改,因为有很多模块。 (我知道我可以将stdoutredirect到一个文件,但即使这样也很慢。)
所以我的问题是我如何redirectstdout到什么都没有,即如何使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.
目前我唯一的想法是创build一个具有写入方法的类(它什么都不做),并将stdoutredirect到这个类的一个实例。
class DontPrint(object): def write(*args): pass dp = DontPrint() sys.stdout = dp
python中是否有内置的机制? 还是有比这更好的东西?
跨平台:
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
一个很好的方法是创build一个小型的上下文处理器,将您的打印件包裹起来。然后,您只需使用is with
-statement来静音所有输出。
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更干净。
(至less在我的系统上),写入os.devnull比写入DontPrint类要快5倍
#!/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),则可以将输出redirect到/dev/null
:
python myprogram.py > /dev/null
对于Windows:
python myprogram.py > nul
在你的下一个项目中,使用日志logging模块,而不是打印垃圾到标准输出/标准错误。
这个怎么样:
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()
这将根据should_hide_output()
的结果使用contextlib模块中的function来隐藏您尝试运行的任何命令的输出,然后在该函数运行完毕后恢复输出行为。
如果要隐藏标准错误输出,则从stack.enter_context(redirect_stderr(null_stream))
导入redirect_stderr
,并添加一行说stack.enter_context(redirect_stderr(null_stream))
。
主要的缺点是,这只适用于Python 3.4及更高版本。
你的类将工作得很好(除了write()
方法的名字 – 它需要被称为write()
,小写)。 只要确保在另一个variables中保存了一个sys.stdout
的副本。
如果你在一个* NIX,你可以做sys.stdout = open('/dev/null')
,但是这比你自己的类更便于移植。
你为什么不试试这个?
sys.stdout.close() sys.stderr.close()