sys.stdout 不会重新分配给sys.__stdout__



我对Python很陌生,所以我仍然只是在学习这门语言。我遇到的一件事是重新分配sys.stdout以更改打印的默认输出。所以我写了这个作为测试:

import sys
sys.stdout = open('log.txt','a')
print('hey')
sys.stdout.close()
sys.stdout = sys.__stdout__
print('hi')

"嘿"被写入文件,但"嗨"没有出现。但是,这按预期工作,"hey"被写入文件,"hi"被打印到控制台输出:

import sys
sys.__stdout__ = sys.stdout
sys.stdout = open(r'C:UsersVincentDocumentsPythonlog.txt','a')
print('hey')
sys.stdout.close()
sys.stdout = sys.__stdout__
print('hi')

简而言之,这是一个无关紧要的小问题,我只是想知道是否有明显的原因导致它没有按照应有的方式工作。我已经在Windows 7 Home Premium上尝试过这个,在v3.2.3和我的便携式pythonv3.2.1上使用IDLE和pyscripter。

在 IDLE 中,sys.__stdout__ 是程序的原始标准输出 - 它无处可去,因为它不是控制台应用程序。 换句话说,IDLE 本身已经用其他东西(它自己的控制台窗口)替换了sys.stdout,所以你通过将自己的stdout替换为 __stdout__ 来倒退两步。

我会尝试这种解决方法(根本不使用sys.__stdout__,因为您的环境可能会使sys.stdoutsys.__stdout__都不同):

old_stdout = sys.stdout
sys.stdout = open('log.txt','a')
print('hey')
sys.stdout.close()
sys.stdout = old_stdout

备份sys.stdout的引用似乎是最安全的方法。在另一种略有不同的情况下工作:来自Jupyter笔记本的stdout重定向降落在终端中

这是一个上下文管理器,可以为您备份sys.std<in|out|err>的旧状态,作为其他答案的补充。

就个人而言,我将它与基于 PyQt5 的程序一起使用,只要应用程序正在运行,标准输出就会重定向到基于文本的小部件。关闭应用程序后,输出将重定向回我的 IDE 控制台。

import sys
class SysStdRedirection:
    """Any change done to `sys.std<in|out|err>` inside this context manager will
       be reverted upon exit."""
    def __init__(self):
        for x in ("stdin", "stdout", "stderr"):
            setattr(self, x, getattr(sys, x))
    def __enter__(self):
        pass
    def __exit__(self, error_type=None, value=None, traceback=None):
        for x in ("stdin", "stdout", "stderr"):
            setattr(sys, x, getattr(self, x))

用法:

with SysStdRedirection():
    sys.stdout = open('log.txt', 'a')
    print('hey')
    sys.stdout.close()
print('hi')

最新更新