因此,我使用了一些库(不幸的是,很多我的烦恼)打印到某些调试信息的标准输出。用于获取用户输入和输出印刷在终端上,这当然需要标准输出在Python中杀死标准输出get_line_buffer()
import sys,os
sys.stdout = open(os.devnull,'wb')
我最近添加代码:好的,没问题,我只是禁用它。但同样,没有任何问题,而不是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()
我也试着sys.stdout = sys.__stdout__
的get_line_buffer()
呼叫前右,但也不管用。任何帮助或解释非常感谢。
我会发送一个拉请求到那些库来代替使用'logging',因为从库代码打印到stdout *或* stderr是荒谬的。或者至少提交一个错误报告。也许名字和耻辱:P –
我也只写了一个快速包装类,它似乎代替'stdout'的任何东西都会破坏readline行为。 –
谢谢,我确实这么做了,但同时我还是很想知道_why_这是怎么回事:) – TheSchwa