我正在编写一些使用sys.stderr.write来报告输入错误的代码的单元测试。这是应该的,但这会破坏单元测试输出。有没有办法告诉Python不输出单个命令的错误消息,àla2> /dev/null
?
答案 0 :(得分:24)
我建议写一个上下文管理器:
import contextlib
import sys
@contextlib.contextmanager
def nostderr():
savestderr = sys.stderr
class Devnull(object):
def write(self, _): pass
def flush(self): pass
sys.stderr = Devnull()
try:
yield
finally:
sys.stderr = savestderr
现在,将您想要在其中抑制的stderr的任何代码段包装在with nostderr():
中,并且您具有所需的本地化,临时,保证可逆的stderr抑制。
答案 1 :(得分:12)
您可以创建一个对其输出不执行任何操作的虚拟文件对象,并将stderr设置为:
class NullWriter:
def write(self, s):
pass
sys.stderr = NullWriter()
如果您只想在特定时间内安静stderr,可以使用with
语句,如下所示:
class Quieter:
def __enter__(self):
self.old_stderr = sys.stderr
sys.stderr = NullWriter()
def __exit__(self, type, value, traceback):
sys.stderr = self.old_stderr
with Quieter():
# Do stuff; stderr will be suppressed, and it will be restored
# when this block exits
需要Python 2.6或更高版本,或者您可以在Python 2.5中使用from __future__ import with_statement
。
答案 2 :(得分:5)
另一种可能性(除了分配给sys.stderr
之外)是构造代码以将错误写入提供的文件,但将该文件默认为sys.stderr。然后,您可以在测试期间提供DevNull编写器。
如果您确实要重新分配sys.stderr,可以使用unittest框架为您管理它:
class DevNull(object):
def write(self, data):
pass
class MyTestCase(unittest.TestCase):
def setUp(self):
self.old_stderr = sys.stderr
sys.stderr = DevNull()
def tearDown(self):
sys.stderr = self.old_stderr
这样,每个测试dev-null的stderr,但然后在测试结束时恢复它。
答案 3 :(得分:4)
class DevNull(object):
def write(self, data): pass
sys.stderr = DevNull()
为了获得一个不那么永久的解决方案,可以找出类似如下的内容:
_stderr = None
def quiet():
global _stderr
if _stderr is None:
_stderr = sys.stderr
sys.stderr = DevNull()
def verbose():
global _stderr
if _stderr is not None:
sys.stderr = _stderr
_stderr = None
功能名称可能更好