我有一个基于 Python 的应用程序,可以在简单的读取-评估-打印循环中接受一些命令。我正在使用
raw_input('> ')
来获取输入。在基于 Unix 的系统上,我还import readline
让事情表现得更好一点。这一切都运行良好。
问题是有异步事件传入,我想在它们发生时立即打印输出。不幸的是,这让事情看起来很丑陋。输出后,“>”字符串不会再次出现,如果用户输入了一半内容,它会将文本切成两半。它可能应该在打印某些内容后重新绘制用户正在处理的文本。
这看起来一定是一个已解决的问题。正确的方法是什么?
另请注意,我的一些用户是基于 Windows 的。
蒂亚
编辑:接受的答案在 Unixy 平台下工作(当 readline 模块可用时),但如果有人知道如何在 Windows 下工作,我们将不胜感激!
也许这样的事情就能解决问题:
#!/usr/bin/env python2.6
from __future__ import print_function
import readline
import threading
PROMPT = '> '
def interrupt():
print() # Don't want to end up on the same line the user is typing on.
print('Interrupting cow -- moo!')
print(PROMPT, readline.get_line_buffer(), sep='', end='')
def cli():
while True:
cli = str(raw_input(PROMPT))
if __name__ == '__main__':
threading.Thread(target=cli).start()
threading.Timer(2, interrupt).start()
我不认为 stdin 是线程安全的,因此您最终可能会因为中断线程而丢失字符(用户必须在
interrupt
末尾重新输入)。我在 interrupt
通话中夸大了 time.sleep
时间。 readline.get_line_buffer
调用不会显示丢失的字符,所以一切正常。
请注意,stdout 本身不是线程安全的,因此如果您有多个中断执行线程,这仍然可能看起来很糟糕。
运行这个:
python -m twisted.conch.stdio
您将获得一个漂亮的、彩色的、异步 REPL,无需使用线程。当您输入提示时,事件循环正在运行。
查看代码模块,它还可以让你创建用于解释Python代码的对象(无耻插件)https://github.com/iridium172/PyTerm让你创建处理原始键盘输入的交互式命令行程序(如^C)将引发键盘中断)。
其他一些方法:
prompt_toolkit
库(我相信这是IPython内部使用的)readline.get_line_buffer
重新打印中断的行。这有点没有答案,但我会查看 IPython 的代码,看看他们是如何做到这一点的。
我认为你有两个基本选择: