如何使用`with`语句来压缩`sys.stdout`或`sys.stderr`?

时间:2018-06-05 03:23:44

标签: python stdout stderr suppress dev-null

我尝试使用with语句单独取消sys.stdoutsys.stderr我发现tutorial没有&{} #39;工作。我正在使用Python 3.6.4,我认为该教程是Python 2的某个版本。

I looked it up on SO并找到了一些但是应用程序不起作用或不适用于这种情况。

这不适用:Python subprocess supress stdout and stderr

无法使任何with语句生效: Suppress stdout / stderr print from Python functions

这是针对fortran:Redirecting FORTRAN (called via F2PY) output in Python

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

2 个答案:

答案 0 :(得分:3)

我使用以下一个:

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

答案 1 :(得分:2)

我使用这样的东西:

public show(clazz: new (...args: any[]) => ChartModal): void
{
}

示例:

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

<强>输出

Before
After
Before
After

注意:

  • 我将我的导入放在方法中以保持清洁,但通常这会在一个模块文件中,导入位于顶部。
  • 抑制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) 方法中的异常的方式。您可能会考虑制作更强大的退出方法。