2016-06-10 65 views
1

我正在寫一個小的單一功能,旨在用一個時間延遲來請求用戶輸入。當時間延遲耗盡時,函數應返回None而不是用戶的響應,然後應該繼續執行腳本的其餘部分。如何從函數中定義的信號處理函數返回控件?

在當前的實現中,用戶輸入工作,超時工作,超時消息由函數中定義的信號處理函數(我打算讓這個外部函數相當獨立)打印。然而,處理然後暫停(而不是退出在main函數中定義的while循環),我不知道爲什麼。

我該如何獲得處理才能繼續?我是否以某種方式濫用signal?可以使用lambda代替處理函數的顯式定義的函數嗎?

#!/usr/bin/env python 

from __future__ import print_function 
import signal 

import propyte 

def main(): 

    response = "yes" 
    while response is not None: 
     response = get_input_nonblocking(
      prompt = "ohai? ", 
      timeout = 5 
     ) 
    print("start non-response procedures") 
    # do things 

def get_input_nonblocking(
    prompt   = "", 
    timeout   = 5, 
    message_timeout = "prompt timeout" 
    ): 
    def timeout_manager(signum, frame): 
     print(message_timeout) 
    #signal.signal(signal.SIGALRM, lambda: print(message_timeout)) 
    signal.signal(signal.SIGALRM, timeout_manager) 
    signal.alarm(timeout) 
    try: 
     response = propyte.get_input(prompt) 
     return response 
    except: 
     return None 

if __name__ == '__main__': 
    main() 

回答

2

你得到的東西幾乎就在那裏,但是你需要在信號處理程序中引發一個異常。 raw_input將會阻塞,直到發生任何輸入或異常。如果您在信號處理程序中引發異常,則會中斷raw_input並且執行將落入您的get_input_non_blocking函數中的except。這裏有一個玩具的例子。

import signal 
def timeout(signum, frame): 
    raise IOError("bye!") 

signal.signal(signal.SIGALRM, timeout) 
def input(): 
    try: 
      print("omgplz: ") 
      return raw_input() 
    except IOError: 
      return None 

signal.alarm(5) 
txt = input() 
signal.alarm(0) 
print(txt) 

有一些更多的討論,並在這個答案在這裏使用select另一種方法:Keyboard input with timeout in Python

希望幫助!