我有一个基于Python的应用程序,可以在简单的read-eval-print-loop中接受一些命令。我正在使用raw_input('> ')
来获取输入。在基于Unix的系统上,我还import readline
使事情表现得更好一些。这一切都很好。
问题是有异步事件进入,我想尽快打印输出。不幸的是,这让事情看起来很难看。输出后,“>”字符串不再显示,如果用户输入内容的一半,则会将文本切成两半。它可能应该在打印之后重新绘制用户正在进行的文本。
这似乎必须是一个已解决的问题。这样做的正确方法是什么?
另请注意,我的一些用户是基于Windows的。
TIA
编辑:接受的答案适用于Unixy平台(当readline模块可用时),但是如果有人知道如何在Windows下完成这项工作,那将非常感谢!
答案 0 :(得分:8)
也许这样的事情可以解决问题:
#!/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
时间。 <{1}}调用不会显示丢失的字符,所以一切都好了。
请注意,stdout本身不是线程安全的,所以如果你有多个执行中断线程,那么这仍然看起来很糟糕。
答案 1 :(得分:5)
为什么要使用raw_input()
编写自己的REPL?你看过cmd.Cmd
班了吗? 修改:我刚刚找到sclapp库,这也可能很有用。
注意:cmd.Cmd
类(和sclapp)可能会也可能不会直接支持您的原始目标;您可能必须将其子类化并根据需要进行修改以提供该功能。
答案 2 :(得分:2)
运行这个:
python -m twisted.conch.stdio
你会得到一个漂亮的彩色异步REPL,而不使用线程。键入提示时,事件循环正在运行。
答案 3 :(得分:0)
查看代码模块,它还允许您创建用于解释python代码的对象(无耻插件)https://github.com/iridium172/PyTerm允许您创建处理原始键盘输入的交互式命令行程序(如^ C将引发KeyboardInterrupt)。
答案 4 :(得分:-1)
这是一种非答案,但我会查看IPython的代码,看看他们是如何做的。
答案 5 :(得分:-1)
我认为你有两个基本选择: