在 python 中杀死标准输出会中断 get_line_buffer()
Killing stdout in python breaks get_line_buffer()
所以我正在使用一些库(不幸的是,这让我很懊恼)打印到标准输出以获得某些调试信息。好的,没问题,我只是禁用了它:
import sys,os
sys.stdout = open(os.devnull,'wb')
我最近添加了用于在终端中获取用户输入和打印输出的代码,这当然需要 stdout。但同样,没问题,而不是 print
我可以这样做:
sys.__stdout__.write('text\n')
最后,因为我在一个单独的线程中执行 raw_input
并且程序的输出可能会打断用户的输入,所以我想按照 in the first part of this answer 所述重新回显测试以使其更或使用 readline.get_line_buffer()
不太无缝。例如,如果用户输入 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__
,但这也不起作用。非常感谢任何帮助或解释。
当您重定向标准输出时,raw_input()
停止工作。
如果您在 raw_input()
之前尝试 sys.stdout = sys.__stdout__
它会再次起作用。
stdin
和 stdout
都需要连接到终端才能使 raw_input
工作。
所以我正在使用一些库(不幸的是,这让我很懊恼)打印到标准输出以获得某些调试信息。好的,没问题,我只是禁用了它:
import sys,os
sys.stdout = open(os.devnull,'wb')
我最近添加了用于在终端中获取用户输入和打印输出的代码,这当然需要 stdout。但同样,没问题,而不是 print
我可以这样做:
sys.__stdout__.write('text\n')
最后,因为我在一个单独的线程中执行 raw_input
并且程序的输出可能会打断用户的输入,所以我想按照 in the first part of this answer 所述重新回显测试以使其更或使用 readline.get_line_buffer()
不太无缝。例如,如果用户输入 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__
,但这也不起作用。非常感谢任何帮助或解释。
当您重定向标准输出时,raw_input()
停止工作。
如果您在 raw_input()
之前尝试 sys.stdout = sys.__stdout__
它会再次起作用。
stdin
和 stdout
都需要连接到终端才能使 raw_input
工作。