2009-01-12 54 views
12

我有一个基于Python的应用程序,可以在简单的read-eval-print-loop中接受一些命令。我使用raw_input('> ')来获得输入。在基于Unix的系统上,我也使用import readline来使事情表现得更好一些。所有这些工作正常。如何实现很好地处理异步输出的python REPL?

问题是,有异步事件进来,我想打印输出一旦发生。不幸的是,这使得事情看起来很丑。输出后“>”字符串不再显示,并且如果用户在输入内容的一半时,则会将其文本删减一半。它应该在打印某些内容后重新绘制用户的正在进行的文本。

这似乎是它必须解决的问题。什么是正确的方法来做到这一点?

另请注意,我的一些用户是基于Windows的。

TIA

编辑:接受的答案工作下Unixy平台(当readline的模块可用),但如果有人知道如何使Windows下这项工作,这将是非常感谢!

回答

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() 

我不认为标准输入是线程安全的,所以你可以最终失去字符中断线程(用户将不得不重新键入interrupt的末尾)。我通过拨打time.sleep来夸大interrupt的时间。 readline.get_line_buffer调用不会显示丢失的字符,所以一切正常。

请注意,标准输出本身不是线程安全的,所以如果你有多个中断执行线程,这仍然可能最终看起来很糟糕。

+0

谢谢,readline.get_line_buffer()是一个好的开始。如果任何人有任何关于在Windows(这没有readline模块),使这项工作的提示,让我知道。 – andy 2009-01-19 19:02:10

+0

它可以在Cygwin中工作吗? – cdleary 2009-01-20 04:59:28

-1

这是一种非答案,但我会看IPython的代码,看看他们是如何做到这一点。

-1

我认为你有两个基本选择:

  1. 同步您的输出(即阻塞,直到它回来)
  2. 独立的输入和你(asyncronous)输出,也许在两个单独的列。
5

你为什么要用raw_input()写自己的REPL?你看过cmd.Cmd课吗? 编辑:我刚刚找到sclapp库,这也可能有用。

注意:cmd.Cmd类(和sclapp)可能会也可能不会直接支持您的原始目标;您可能需要对其进行细分并根据需要对其进行修改以提供该功能。

0

查看代码模块,它可以让你创建解释python代码的对象(无耻插件)https://github.com/iridium172/PyTerm让你创建处理原始键盘输入的交互式命令行程序(例如^ C将引发KeyboardInterrupt)。

2

运行以下命令:

python -m twisted.conch.stdio 

你会得到一个不错的,彩色的,异步REPL,不使用线程。在输入提示时,事件循环正在运行。