2014-01-14 37 views
29

我正在Python中編寫一個命令行實用程序,因爲它是生產代碼,應該能夠乾淨地關閉而不傾銷一堆東西(錯誤代碼,堆棧跟蹤等等)到屏幕上。這意味着我需要捕捉鍵盤中斷。在程序關閉期間在Python中捕捉KeyboardInterrupt

我同時使用像一個try catch塊已經試過:

if __name__ == '__main__': 
    try: 
     main() 
    except KeyboardInterrupt: 
     print 'Interrupted' 
     sys.exit(0) 

和捕獲信號本身(如this post):

import signal 
import sys 

def sigint_handler(signal, frame): 
    print 'Interrupted' 
    sys.exit(0) 
signal.signal(signal.SIGINT, sigint_handler) 

這兩種方法似乎運作得很好,在正常操作。但是,如果在應用程序末尾的清理代碼中出現中斷,Python似乎總是在屏幕上打印某些內容。捕獲中斷使

^CInterrupted 
Exception KeyboardInterrupt in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802852b90>> ignored 

而處理信號給出任何

^CInterrupted 
Exception SystemExit: 0 in <Finalize object, dead> ignored 

^CInterrupted 
Exception SystemExit: 0 in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802854a90>> ignored 

不僅是這些醜陋的錯誤,他們不是非常有幫助的(尤其是結束沒有源代碼的用戶)!

這個應用程序的清理代碼相當大,所以這個問題很有可能會被真實用戶擊中。有什麼方法可以捕捉或阻止這種輸出,還是僅僅需要處理?

+2

你爲什麼不更換'SYS。 stdout' /'sys.stderr'?像'sys.stderr = open(os.devnull,'w')'?.如果你真的不關心最終產出,那麼這看起來就像是一個明顯的解決方案。 – Bakuriu

+1

有一個'os._exit',但它看起來像鼻子惡魔給我。你的清理代碼在哪裏,你使用[atexit](http://docs.python.org/2/library/atexit.html#module-atexit)模塊嗎? – wim

+1

@Bakuriu:重定向stderr會使輸出安靜,同時也會壓縮用戶可以執行某些操作的合法錯誤,例如文件未找到或主機無法訪問。 – Dan

回答

5

在開始清理代碼之前,可以通過調用signal.signal(signal.SIGINT, signal.SIG_IGN)來關閉關機後的SIGINT。

47

結帳this thread,它有一些關於退出和回溯的有用信息。

如果您更感興趣的是剛殺程序,嘗試這樣的事情(這將腿從清理代碼下以及OUT):

if __name__ == '__main__': 
    try: 
     main() 
    except KeyboardInterrupt: 
     print 'Interrupted' 
     try: 
      sys.exit(0) 
     except SystemExit: 
      os._exit(0) 
+0

我建議除了as,然後抓取和重用退出代碼。 – wizzwizz4

相關問題