为什么 devnull 在此上下文管理器中定义时无法隐藏控制台输出?

Why does devnull not work at hiding console output when it is defined within this context manager?

我定义了一个上下文管理器,目的是 "silencing" 通过临时重新定义 stdout 和 stderr 来输出一些 Python 代码。

在代码的main函数中定义devnull时,代码的输出成功静音,但是在context manager中定义devnull时,代码的输出没有静音

这是为什么?上下文管理器如何在定义 devnull 的同时使输出静音?

import os
import sys

def main():

    print("hello")

    devnull = open(os.devnull, "w")
    with silence(
        stdout = devnull,
        stderr = devnull
        ):
        print("there")

    print("world")

class silence(object):

    def __init__(
        self,
        stdout = None,
        stderr = None
        ):
        if stdout == None and stderr == None:
            devnull = open(os.devnull, "w")
        self._stdout = stdout or sys.stdout
        self._stderr = stderr or sys.stderr

    def __enter__(
        self
        ):
        self.old_stdout = sys.stdout
        self.old_stderr = sys.stderr
        self.old_stdout.flush()
        self.old_stderr.flush()
        sys.stdout = self._stdout
        sys.stderr = self._stderr

    def __exit__(
        self,
        exc_type,
        exc_value,
        traceback
        ):
        self._stdout.flush()
        self._stderr.flush()
        sys.stdout = self.old_stdout
        sys.stderr = self.old_stderr

if __name__ == "__main__":
    main()

在您的 __ init __ 方法中,当 stderrstdout 参数为 None 时,您定义了 devnull 但您没有将此值分配给 stderrstdout。因此 stderrstdout 是错误的,因此输出流保持为 sys.stderrsys.stdout.

class silence(object):

    def __init__(
        self,
        stdout = None,
        stderr = None
        ):
        if stdout == None and stderr == None:
            devnull = open(os.devnull, "w")
            # Assign devnull to stdout and stderr
            stdout = devnull
            stderr = devnull
        self._stdout = stdout or sys.stdout
        self._stderr = stderr or sys.stderr