2016-10-06 56 views
1

什麼是使用curses模塊快速退出Python程序的無限循環的最佳方式?Python Curses:快速退出程序

我已經嘗試添加在循環的結束加上此NODELAY()方法:

if screen.getch() == ord('q'): 
    break 

然而,它需要2-3秒,使在環的一個迭代的所有函數調用。而且由於應用程序的原因,每5秒更頻繁地運行一次循環是沒有意義的。這意味着,爲了讓我退出該計劃的工作方式,我有時必須按住'q'2-8秒。

我的代碼如下所示:

import curses 
import time 

def main(screen): 
    refresh_rate = 5 
    screen.nodelay(1) 

    # Infinite loop. Displays information and updates it 
    # every (refresh_rate) # of seconds 

    while True: 

     # Makes several http requests 
     # and passes responses through multiple functions 

     # Escape infinite loop 
     if screen.getch() == ord('q'): 
      break 

     # Wait before going through the loop again 
     time.sleep(refresh_rate) 

if __name__ == "__main__": 
    curses.wrapper(main) 

我其他的解決辦法是更換,而真正有:

loop = 1 
while loop: 

    #Loop code 

if screen.getch() == ord('q'): 
    loop = -1 

這樣一來,就沒有必要按住「Q」退出該程序。但按'q'一次後仍然可能需要8秒才能退出。

由於顯而易見的原因,這似乎不是退出程序的最佳方式。我很確定應該有更好的(更快的)解決方案。

除此之外,程序工作正常。這是兩行300多行的文件,所以我只是用我的嘗試解決方案發布代碼的相關部分。

回答

1

考慮到你已經有了節點,通常的方法是使用一個小的(20-50毫秒)時間的napms,並且處理你的5秒的目標,在幾次(10-25)重複之後運行函數getch/napms循環。

混合詛咒和標準I/O實際上不能很好地工作,除非在兩者之間進行切換時注意刷新事物。

+0

這正是我所期待的!必須將循環放在一個單獨的函數中才能工作,因爲顯然,從getch/napms循環中斷不會從主循環中斷開。所以我用'return'替換getch/napms循環中的'break'。謝謝。 –

0

可能發生的情況是您的'q'來自getch()sleep調用之間。鑑於getch()需要幾分之一秒才能執行,而sleep將程序鎖定5秒,所以無論何時您按下某個鍵,您都將等待。

退出任何python腳本最簡單的方法是按Ctrl-C - 它產生一個KeyBoardInterrupt異常可以像處理:

try: 
while True: 
    do_something() 
except KeyboardInterrupt: 
    pass 

當然,如果這意味着是一個面向用戶的應用程序,可能不夠。但是,如果沒有完整的事件循環和允許它們退出的UI,任何生產應用程序都不可能運行。

最後,如果你想要做你已經做的另一種方式,你可以使用:

import sys 
sys.stdin.read(1) 

要一次讀1輪輪空的用戶輸入。如果我是你,我會去參加Ctrl-C的路線。

+0

我不想爲此應用程序使用「Ctrl-C」。但是,感謝您展示如何處理'KeyBoardInterrupt'。我將它添加到我的代碼以防萬一。 –