13

我有一个基于 Python 的应用程序,它可以在一个简单的 read-eval-print-loop 中接受一些命令。我raw_input('> ')用来获取输入。在基于 Unix 的系统上,我也import readline让事情表现得更好一点。所有这一切都很好。

问题是有异步事件进来,我想在它们发生时立即打印输出。不幸的是,这让事情看起来很难看。"> " 字符串在输出后不会再次出现,如果用户正在输入一半内容,它会将文本切成两半。它可能应该在打印某些内容后重绘用户正在处理的文本。

这似乎必须是一个已解决的问题。这样做的正确方法是什么?

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

TIA

编辑:接受的答案在 Unixy 平台下工作(当 readline 模块可用时),但如果有人知道如何在 Windows 下工作,将不胜感激!

4

6 回答 6

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.sleepreadline.get_line_buffer

请注意,stdout 本身不是线程安全的,因此如果您有多个中断的执行线程,这仍然会看起来很糟糕。

于 2009-01-12T21:33:20.210 回答
5

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

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

于 2009-01-13T21:44:41.030 回答
2

运行这个:

python -m twisted.conch.stdio

您将获得一个漂亮的、彩色的、异步的 REPL,而无需使用线程。当您输入提示时,事件循环正在运行。

于 2010-12-22T10:57:43.050 回答
0

查看代码模块,它还允许您创建用于解释 python 代码的对象(无耻插件)https://github.com/iridium172/PyTerm允许您创建处理原始键盘输入的交互式命令行程序(如 ^C 将引发键盘中断)。

于 2010-12-09T02:15:57.767 回答
-1

这是一个无法回答的问题,但我会查看IPython的代码,看看他们是如何做到的。

于 2009-01-12T23:04:43.893 回答
-1

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

  1. 同步你的输出(即阻塞直到它回来)
  2. 将您的输入和您的(异步)输出分开,可能在两个单独的列中。
于 2009-01-13T15:36:14.830 回答