问题:在python中将stdout重定向为“ nothing”
我有一个大型项目,其中包含足够多的模块,每个模块都将一些内容打印到标准输出中。现在,随着项目规模的扩大,没有大型项目。的print
报表打印在其上制作的节目相当慢性病了很多。
因此,我现在想在运行时决定是否将任何内容打印到标准输出。我无法对模块进行更改,因为其中有很多更改。(我知道我可以将标准输出重定向到文件,但即使这样也很慢。)
所以我的问题是如何将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.
目前,我唯一的想法是制作一个具有write方法的类(不执行任何操作),然后将stdout重定向到该类的实例。
class DontPrint(object):
def write(*args): pass
dp = DontPrint()
sys.stdout = dp
在python中有内置的机制吗?还是有比这更好的东西?
I have a large project consisting of sufficiently large number of modules, each printing something to the standard output. Now as the project has grown in size, there are large no. of print
statements printing a lot on the std out which has made the program considerably slower.
So, I now want to decide at runtime whether or not to print anything to the stdout. I cannot make changes in the modules as there are plenty of them. (I know I can redirect the stdout to a file but even this is considerably slow.)
So my question is how do I redirect the stdout to nothing ie how do I make the print
statement do nothing?
# 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.
Currently the only idea I have is to make a class which has a write method (which does nothing) and redirect the stdout to an instance of this class.
class DontPrint(object):
def write(*args): pass
dp = DontPrint()
sys.stdout = dp
Is there an inbuilt mechanism in python for this? Or is there something better than this?
回答 0
跨平台:
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
Cross-platform:
import os
import sys
f = open(os.devnull, 'w')
sys.stdout = f
On Windows:
f = open('nul', 'w')
sys.stdout = f
On Linux:
f = open('/dev/null', 'w')
sys.stdout = f
回答 1
这样做的一种好方法是创建一个用于包装打印内容的小型上下文处理器。然后,您可以使用with
-statement来使所有输出静音。
Python 2:
import os
import sys
from contextlib import contextmanager
@contextmanager
def silence_stdout():
old_target = sys.stdout
try:
with open(os.devnull, "w") as new_target:
sys.stdout = new_target
yield new_target
finally:
sys.stdout = old_target
with silence_stdout():
print("will not print")
print("this will print")
Python 3.4+:
Python 3.4具有内置的上下文处理器,因此您可以像这样简单地使用contextlib:
import contextlib
with contextlib.redirect_stdout(None):
print("will not print")
print("this will print")
运行此代码仅显示输出的第二行,而不输出第一行:
$ python test.py
this will print
这可以跨平台(Windows + Linux + Mac OSX)运行,并且比其他解决方案更干净。
A nice way to do this is to create a small context processor that you wrap your prints in. You then just use is in a with
-statement to silence all output.
Python 2:
import os
import sys
from contextlib import contextmanager
@contextmanager
def silence_stdout():
old_target = sys.stdout
try:
with open(os.devnull, "w") as new_target:
sys.stdout = new_target
yield new_target
finally:
sys.stdout = old_target
with silence_stdout():
print("will not print")
print("this will print")
Python 3.4+:
Python 3.4 has a context processor like this built-in, so you can simply use contextlib like this:
import contextlib
with contextlib.redirect_stdout(None):
print("will not print")
print("this will print")
Running this code only prints the second line of output, not the first:
$ python test.py
this will print
This works cross-platform (Windows + Linux + Mac OSX), and is cleaner than the ones other answers imho.
回答 2
如果您使用的是python 3.4或更高版本,则可以使用标准库提供一种简单安全的解决方案:
import contextlib
with contextlib.redirect_stdout(None):
print("This won't print!")
If you’re in python 3.4 or higher, there’s a simple and safe solution using the standard library:
import contextlib
with contextlib.redirect_stdout(None):
print("This won't print!")
回答 3
(至少在我的系统上)似乎写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
(at least on my system) it appears that writing to os.devnull is about 5x faster than writing to a DontPrint class, i.e.
#!/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)
gave the following output:
<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
回答 4
如果您在Unix环境(包括Linux)中,则可以将输出重定向到/dev/null
:
python myprogram.py > /dev/null
对于Windows:
python myprogram.py > nul
If you’re in a Unix environment (Linux included), you can redirect output to /dev/null
:
python myprogram.py > /dev/null
And for Windows:
python myprogram.py > nul
回答 5
这个怎么样:
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和更高版本。
How about this:
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()
This uses the features in the contextlib module to hide the output of whatever command you are trying to run, depending on the result of should_hide_output()
, and then restores the output behavior after that function is done running.
If you want to hide standard error output, then import redirect_stderr
from contextlib
and add a line saying stack.enter_context(redirect_stderr(null_stream))
.
The main downside it that this only works in Python 3.4 and later versions.
回答 6
您的类将正常工作(write()
方法名称除外-需要将其称为write()
小写)。只要确保将副本保存sys.stdout
在另一个变量中即可。
如果您使用的是* NIX,则可以执行sys.stdout = open('/dev/null')
,但这比滚动自己的类要轻巧。
Your class will work just fine (with the exception of the write()
method name — it needs to be called write()
, lowercase). Just make sure you save a copy of sys.stdout
in another variable.
If you’re on a *NIX, you can do sys.stdout = open('/dev/null')
, but this is less portable than rolling your own class.
回答 7
您可以嘲笑它。
import mock
sys.stdout = mock.MagicMock()
You can just mock it.
import mock
sys.stdout = mock.MagicMock()
回答 8
你为什么不试试这个?
sys.stdout.close()
sys.stderr.close()
Why don’t you try this?
sys.stdout.close()
sys.stderr.close()
回答 9
sys.stdout = None
可以的print()
情况下。但是,如果您调用sys.stdout的任何方法(例如),则可能会导致错误sys.stdout.write()
。
在文档中有一个注释:
在某些情况下,stdin,stdout和stderr以及原始值stdin,stdout和stderr可以为None。对于未连接到控制台的Windows GUI应用程序以及以pythonw开头的Python应用程序,通常是这种情况。
sys.stdout = None
It is OK for print()
case. But it can cause an error if you call any method of sys.stdout, e.g. sys.stdout.write()
.
There is a note in docs:
Under some conditions stdin, stdout and stderr as well as the original
values stdin, stdout and stderr can be None. It is usually
the case for Windows GUI apps that aren’t connected to a console and
Python apps started with pythonw.
回答 10
补充iFreilicht的答案 -适用于python 2和3。
import sys
class NonWritable:
def write(self, *args, **kwargs):
pass
class StdoutIgnore:
def __enter__(self):
self.stdout_saved = sys.stdout
sys.stdout = NonWritable()
return self
def __exit__(self, *args):
sys.stdout = self.stdout_saved
with StdoutIgnore():
print("This won't print!")
Supplement to iFreilicht’s answer – it works for both python 2 & 3.
import sys
class NonWritable:
def write(self, *args, **kwargs):
pass
class StdoutIgnore:
def __enter__(self):
self.stdout_saved = sys.stdout
sys.stdout = NonWritable()
return self
def __exit__(self, *args):
sys.stdout = self.stdout_saved
with StdoutIgnore():
print("This won't print!")