sys.__stdout__ 有效,但 sys.stdout 无效

sys.__stdout__ works but sys.stdout does not

有一个名为 redirect 的函数,它临时将对文件 source 的操作重定向到文件 target

    def redirect(source, target):
    source.flush()
    fd = source.fileno()
    with os.fdopen(os.dup(fd), source.mode) as source2:
        os.dup2(target.fileno(), fd)
        try:
            yield
        finally:
            source.flush()
            os.dup2(source2.fileno(), fd)

它是从与

相同的模块调用的
    with tempfile.TemporaryFile() as tmp:
        with redirect(sys.stdout, tmp), nogil:

编译时,它曾经生成一个 AttributeError

AttributeError: StringIO instance has no attribute 'fileno'

在第 fd = source.fileno().

但是当我把sys.stdout换成sys.__stdout__的时候就没有这个错误了,测试成功了。

现在我真的很困惑,为什么__stdout__有效而stdout无效。

正如 Greg 在评论中提到的那样,那是行不通的。我通常做的是暂时改变我的标准输出。

@contextmanager
def replace_stdout(replacement):
    _stdout = sys.stdout
    sys.stdout = replacement
    try:
        yield
    finally:
        sys.stdout = _stdout

并将该上下文管理器与 :

一起使用
with tempfile.TemporaryFile() as tmp:
    with replace_stdout(sys.stdout, tmp):

这种用法不关心初始标准输出是否有 FD。