如何使用`with` 语句来抑制`sys.stdout` 或`sys.stderr`?

O.r*_*rka 0 python stdout suppress stderr dev-null

我正在尝试使用with声明来抑制sys.stdoutsys.stderr单独使用。 我发现了一个不起作用的教程。我正在使用Python 3.6.4并且我认为该教程是Python 2.

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

这不适用:Python subprocess supress stdout and stderr

无法使任何with语句起作用: Suppress stdout / stderr print from Python functions

这适用于 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
Run Code Online (Sandbox Code Playgroud)

Sra*_*raw 5

我使用以下一个:

from contextlib import redirect_stdout, contextmanager
import os


@contextmanager
def suppress():
    with open(os.devnull, "w") as null:
        with redirect_stdout(null):
            yield
Run Code Online (Sandbox Code Playgroud)

测试:

print("qwer")
with suppress():
    print("asdf")
print("ghjk")
# qwer
# ghjk
Run Code Online (Sandbox Code Playgroud)

更新

一个更好的:

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
Run Code Online (Sandbox Code Playgroud)