2009-01-12 38 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,不使用線程。在輸入提示時,事件循環正在運行。