简体   繁体   English

sys.stdout 没有重新分配给 sys.__stdout__

[英]sys.stdout not reassigning to sys.__stdout__

I'm pretty new to Python so I am still just learning the language.我对 Python 还很陌生,所以我还在学习这门语言。 One of the things I came across was reassigning sys.stdout to change the default output of print.我遇到的一件事是重新分配 sys.stdout 以更改打印的默认输出。 So I wrote this as a test:所以我写了这个作为测试:

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

'Hey' is written to the file, but 'hi' shows up nowhere. 'Hey' 被写入文件,但 'hi' 没有出现。 However, this works as expected, and 'hey' is written to the file, and 'hi' is printed to the console output:但是,这按预期工作,并且 'hey' 被写入文件,'hi' 被打印到控制台输出:

import sys
sys.__stdout__ = sys.stdout
sys.stdout = open(r'C:\Users\Vincent\Documents\Python\log.txt','a')
print('hey')
sys.stdout.close()
sys.stdout = sys.__stdout__
print('hi')

In short its a small problem that doesnt really matter too much, I am just wondering if there's a discernible reason why its not working the way it should.简而言之,它是一个并不重要的小问题,我只是想知道是否有明显的原因为什么它没有按应有的方式工作。 I have tried this on Windows 7 Home Premium with IDLE and pyscripter on v3.2.3 and my portable python v3.2.1.我已经在 Windows 7 Home Premium 上使用 IDLE 和 v3.2.3 上的 pyscripter 以及我的便携式 python v3.2.1 尝试过这个。

In IDLE, sys.__stdout__ is the program's original standard output - which goes nowhere, since it's not a console application.在 IDLE 中, sys.__stdout__是程序的原始标准输出 - 它无处可去,因为它不是控制台应用程序。 In other words, IDLE itself has already replaced sys.stdout with something else (its own console window), so you're taking two steps backwards by replacing your own stdout with __stdout__ .换句话说,IDLE 本身已经用其他东西(它自己的控制台窗口)替换了sys.stdout ,所以你通过用__stdout__替换你自己的stdout向后退了两步。

I would try this workaround (not using sys.__stdout__ at all because your environment could have made both sys.stdout and sys.__stdout__ distinct):我会尝试这种解决方法(根本不使用sys.__stdout__因为您的环境可能使sys.stdoutsys.__stdout__不同):

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

backuping the reference of sys.stdout seems the safest way to do it.备份sys.stdout的引用似乎是最安全的方法。 Worked in another slightly different case: stdout redirect from Jupyter notebook is landing in the terminal在另一个稍微不同的情况下工作: 来自 Jupyter 笔记本的 stdout 重定向正在登陆终端

Here is a context manager that backups the old states of sys.std<in|out|err> for you, as a complement to the other answers.这是一个上下文管理器,它为您备份sys.std<in|out|err>的旧状态,作为对其他答案的补充。

Personally, I use it with my programs based on PyQt5 where the standard output is redirected towards a text-based widget as long as the app is running.就个人而言,我将它与基于 PyQt5 的程序一起使用,只要应用程序正在运行,标准输出就会重定向到基于文本的小部件。 The output is redirected back to my IDE's console once the app is closed.应用程序关闭后,输出将重定向回我的 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))

Usage:用法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM