<p>我最近遇到了这个问题,希望把这个解决方案留在这里供以后参考。
这些解决方案从终端清除挂起的原始输入(readline)文本,打印新文本,然后将原始输入缓冲区中的内容重新打印到终端。</p>
<p>第一个程序非常简单,但只有在只有一行文本等待原始输入时才能正常工作:</p>
<pre><code>#!/usr/bin/python
import time,readline,thread,sys
def noisy_thread():
while True:
time.sleep(3)
sys.stdout.write('\r'+' '*(len(readline.get_line_buffer())+2)+'\r')
print 'Interrupting text!'
sys.stdout.write('> ' + readline.get_line_buffer())
sys.stdout.flush()
thread.start_new_thread(noisy_thread, ())
while True:
s = raw_input('> ')
</code></pre>
<p>输出:</p>
<pre><code>$ ./threads_input.py
Interrupting text!
Interrupting text!
Interrupting text!
> WELL, PRINCE, Genoa and Lucca are now no more than private estates of the Bo
Interrupting text!
> WELL, PRINCE, Genoa and Lucca are now no more than private estates of the Bo
naparte family. No, I warn you, that if you do not tell me we are at war,
</code></pre>
<p>第二个正确处理2个或更多缓冲线,但有更多(标准)模块依赖性,需要少量终端黑客:</p>
<pre><code>#!/usr/bin/python
import time,readline,thread
import sys,struct,fcntl,termios
def blank_current_readline():
# Next line said to be reasonably portable for various Unixes
(rows,cols) = struct.unpack('hh', fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ,'1234'))
text_len = len(readline.get_line_buffer())+2
# ANSI escape sequences (All VT100 except ESC[0G)
sys.stdout.write('\x1b[2K') # Clear current line
sys.stdout.write('\x1b[1A\x1b[2K'*(text_len/cols)) # Move cursor up and clear line
sys.stdout.write('\x1b[0G') # Move to start of line
def noisy_thread():
while True:
time.sleep(3)
blank_current_readline()
print 'Interrupting text!'
sys.stdout.write('> ' + readline.get_line_buffer())
sys.stdout.flush() # Needed or text doesn't show until a key is pressed
if __name__ == '__main__':
thread.start_new_thread(noisy_thread, ())
while True:
s = raw_input('> ')
</code></pre>
<p>输出。正确清除以前的阅读行:</p>
<pre><code>$ ./threads_input2.py
Interrupting text!
Interrupting text!
Interrupting text!
Interrupting text!
> WELL, PRINCE, Genoa and Lucca are now no more than private estates of the Bo
naparte family. No, I warn you, that if you do not tell me we are at war,
</code></pre>
<hr/>
<p>有用的来源:</p>
<p><a href="https://stackoverflow.com/questions/566746/how-to-get-console-window-width-in-python">How to get Linux console window width in Python</a></p>
<p><a href="https://stackoverflow.com/questions/1396820/apt-like-column-output-python-library/1446973#1446973">apt like column output - python library</a>
(此代码示例演示如何获取Unix或Windows的终端宽度)</p>
<p><a href="http://en.wikipedia.org/wiki/ANSI_escape_code" rel="nofollow noreferrer">http://en.wikipedia.org/wiki/ANSI_escape_code</a></p>