在編寫Python程序時,經常需要設置臨時選擇項,如出現異常時詢問後續操作,或程序開始執行時詢問必要參數等,這時候往往需要用到input
或彈窗等方式向用戶詢問。然而,當程序並不是自己用,或者需要分享給他人的時候,出於穩健性的考慮,我們可能需要爲此類輸入命令設置超時時間,如詢問選擇後若5秒內未得到返回值,就選擇默認參數,並繼續執行後續進程。
然而,通過一段時間的搜索,網上提供了不少超時終止的方法,如採取多線程的方法,或使用包eventlet
,或者使用signal
。經過測試,發現其各自都有一些問題。
- 對於使用
threading
創建多線程的方法來說,實現方法較爲複雜,需要編寫裝飾器,而且若要獲取返回值還需要爲Thread撰寫子類來實現,而這裏只是需要實現一個簡單的超時跳過,大可不必如此大動干戈。 - 對於使用
eventlet
方法實現超時的方法,介紹的文章大部分都是針對爬蟲或大量計算的情況,經過測試發現該方法對input
無效,對於input
來說無論超時多久都不會自動跳過 - 對於使用
signal
的方法,只有Linux\MacOS
平臺下可用,Windows
無法使用
本文通過調用一個簡單的庫實現裝飾器,能夠通過短短8行代碼,實現獲取input詢問輸入,並計時超時後自動拋出異常或設置默認參數繼續執行後續進程。
首先pip install func_timeout
包,將需要詢問的內容封裝進一個函數,併爲其添加func_set_timeout(2)
的裝飾器,參數2
表示超時時間,此處設置爲2s。
import func_timeout
@func_timeout.func_set_timeout(2)
def askChoice():
return input('yes or no:')
try:
s = askChoice()
except func_timeout.exceptions.FunctionTimedOut as e:
s = 'f'
print(s)
程序執行時先調用askChoice
函數,並開始計時,若用戶在計時期間內輸入,則正常傳參,若用戶超時,則觸發func_timeout.exceptions.FunctionTimedOut
異常,try...except
捕捉異常,並進行後續操作。
此方法對於多線程中的子線程內的超時問題也能提供很好的處理,有興趣的同學可以嘗試一下,歡迎討論~