2017-10-16 102 views
2

我正在學習python的信號模塊。請考慮下面的例子:信號模塊不會引發異常

def timeoutFn(func, args=(), kwargs={}, timeout_duration=1, default=None): 
    import signal 

    class TimeoutError(Exception): 
     pass 

    def handler(signum, frame): 
     print "Trying to raise exception" 
     raise TimeoutError 

    # set the timeout handler 
    signal.signal(signal.SIGALRM, handler) 
    signal.alarm(timeout_duration) 
    try: 
     result = func(*args, **kwargs) 
    except TimeoutError as exc: 
     result = default 
    finally: 
     signal.alarm(0) 

    return result 

,並

import time 

def foo(): 
    for i in range(10): 
     time.sleep(0.5) 
     print "Sleeping" 

在調用下面獲取打印功能timeoutFn(foo)但它引發異常。

不應該引發TimeoutError嗎?但是,它所打印的全部是

Sleeping Trying to raise exception 並且程序停止。

+0

它工作正確。你能指望什麼?那個例外被提出了? – Trilliput

+0

打印「嘗試引發異常」後,我沒有收到任何TimeoutError – Aditya

回答

0

這個異常沒有被提出,因爲你抓住它。注意行:

except TimeoutError as exc: 
    result = default 

塊意味着,如果異常TimeoutError已經提出,result將被分配到default(這是None在你的例子)和腳本進一步繼續沒有表現出異常。

更新:

signal.alarm不會停止流動。所以這個異常會由於超時而產生,如果這個腳本將在try塊中,那麼這個異常將被捕獲。如果將timeout_duration增加到3,您將會看到更好的效果。打印幾條「睡眠」消息將會有更多時間。它表明,在引發異常時,解釋器已進入try塊。

+0

該行捕獲'try'塊中發生的異常,而不是嘗試之前發生的異常。 – Aditya

+0

'signal.alarm'不會停止流程。所以這個異常會由於超時而產生,如果腳本將在try塊中,那麼異常將被捕獲。你可以更好地看到,如果你將'timeout_duration'增加到3,它將如何工作。比打印幾個'睡眠'消息有更多的時間。 – Trilliput