【问题标题】:Killing stdout in python breaks get_line_buffer()在 python 中杀死标准输出会破坏 get_line_buffer()
【发布时间】:2017-01-27 10:24:17
【问题描述】:

所以我正在使用一些库(不幸的是,这让我很懊恼)打印到标准输出以获取某些调试信息。好的,没问题,我只是禁用了它:

import sys,os
sys.stdout = open(os.devnull,'wb')

我最近添加了用于在终端中获取用户输入和打印输出的代码,这当然需要标准输出。但同样,没问题,我可以这样做,而不是 print

sys.__stdout__.write('text\n')

最后,由于我在单独的线程中执行 raw_input 并且程序的输出可能会中断用户输入,因此我想按照 in the first part of this answer 的描述重新回显测试,以使其或多或少地使用 @987654326 无缝@。例如,如果用户输入foobar

> foobar

然后另一个线程说Interrupting text! 它应该看起来像:

Interrupting text!
> foobar

但我观察到:

Interrupting text!
>

事实证明readline.get_line_buffer() 始终为空白,并且代码无法重新回显用户输入的内容。如果我删除 sys.stdout 覆盖,一切都会按预期工作(除了现在库的调试输出没有被阻止)。

如果这很重要,我会在 Linux 上使用 Python 2.7。也许我想做的事情是不可能的,但我真的很想知道为什么会这样。在我看来,使用stdout 做事不应该影响stdin 行缓冲区,但我承认我不熟悉底层库或实现。

下面是一个最小的工作示例。只需输入一些内容并等待中断的文本。提示"> " 将被重新回显,但您输入的文本不会。只需注释掉第二行即可查看它是否正常工作。当线程打印时,它将行缓冲区记录到stdin.log

import time,readline,thread,sys,os
sys.stdout = open(os.devnull,'wb')  # comment this line!

def noisy_thread():
  while True:
    time.sleep(5)
    line = readline.get_line_buffer()
    with open('stdin.log','a') as f:
      f.write(time.asctime()+' | "'+line+'"\n')
    sys.__stdout__.write('\r'+' '*(len(line)+2)+'\r')
    sys.__stdout__.write('Interrupting text!\n')
    sys.__stdout__.write('> ' + line)
    sys.__stdout__.flush()

thread.start_new_thread(noisy_thread, ())
while True:
    sys.__stdout__.write('> ')
    s = raw_input()

我也在get_line_buffer() 调用之前尝试过sys.stdout = sys.__stdout__,但这也不起作用。非常感谢任何帮助或解释。

【问题讨论】:

  • 我会向这些库发送拉取请求以使用 logging,因为从库代码打印到 stdout stderr 是荒谬的。或者至少提交一个错误报告。也许名字和耻辱:P
  • 我也刚刚写了一个快速包装类,似乎任何替换 stdout 的东西都会破坏 readline 行为。
  • 谢谢,我确实这样做了,但与此同时,我仍然很想知道为什么会发生这种情况:)
  • 是的,我同意这是一个超级奇怪的问题。

标签: python multithreading stdout raw-input


【解决方案1】:

当您重定向标准输出时,它的 raw_input() 会停止工作。 如果您在raw_input() 之前尝试sys.stdout = sys.__stdout__,它会再次起作用。 stdinstdout 都需要连接到终端,raw_input 才能工作。

【讨论】:

  • 既然你已经这么说了,那就太有道理了;只是无法为自己解决。谢谢!
猜你喜欢
  • 2012-05-22
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
  • 2018-06-27
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
相关资源
最近更新 更多