如何使用"with"语句来抑制"sys.stdout"或"sys.st



我正在尝试使用with语句来单独抑制sys.stdoutsys.stderr我发现一个教程不起作用。 我正在使用Python 3.6.4,我认为本教程是Python 2的某个版本。

我在SO上查找了它,发现了一些,但是应用程序不起作用或不适用于这种情况。

这不适用:Python subprocess supress stdout 和 stderr

无法使任何with语句正常工作: 从 Python 函数中抑制标准输出/标准输出打印

这是针对fortran的:在Python中重定向FORTRAN(通过F2PY调用(输出

from contextlib import contextmanager
@contextmanager
def suppress_console(file=sys.stdout):
with open(os.devnull, "w") as devnull:
old_file = file
file = devnull
try:  
yield
finally:
file = old_file
with suppress_console():
print(1, file=sys.stdout)
# 1

我使用以下一个:

from contextlib import redirect_stdout, contextmanager
import os

@contextmanager
def suppress():
with open(os.devnull, "w") as null:
with redirect_stdout(null):
yield

测试:

print("qwer")
with suppress():
print("asdf")
print("ghjk")
# qwer
# ghjk

更新

一个更好的:

from contextlib import redirect_stdout, redirect_stderr, contextmanager, ExitStack
import os
@contextmanager
def suppress(out=True, err=False):
with ExitStack() as stack:
with open(os.devnull, "w") as null:
if out:
stack.enter_context(redirect_stdout(null))
if err:
stack.enter_context(redirect_stderr(null))
yield

我使用这样的东西:

class Suppress:
def __init__(self, *, suppress_stdout=False, suppress_stderr=False):
self.suppress_stdout = suppress_stdout
self.suppress_stderr = suppress_stderr
self.original_stdout = None
self.original_stderr = None
def __enter__(self):
import sys, os
devnull = open(os.devnull, "w")
# Suppress streams
if self.suppress_stdout:
self.original_stdout = sys.stdout
sys.stdout = devnull
if self.suppress_stderr:
self.original_stderr = sys.stderr
sys.stderr = devnull
def __exit__(self, *args, **kwargs):
import sys
# Restore streams
if self.suppress_stdout:
sys.stdout = self.original_stdout
if self.suppress_stderr:
sys.stderr = self.original_stderr

例:

import sys
print("Before")
with Suppress(suppress_stdout=True):
print("Inside")
print("After")
print("Before", file=sys.stderr)
with Suppress(suppress_stderr=True):
print("Inside", file=sys.stderr)
print("After", file=sys.stderr)

输出

以前 后 以前 后

记:

  • 我将导入放在清洁方法中,但通常这将放在顶部带有导入的模块文件中。
  • 抑制 stderr 是有风险的,特别是因为我(不是(在__exit__方法中处理异常的方式。 您可以考虑制定更可靠的退出方法。

最新更新