2012-09-17 19 views
1

從功能內到exit()是不好的形式嗎?從函數退出()它是不好的形式嗎?

def respond_OK(): 
    sys.stdout.write('action=OK\n\n') 
    sys.stdout.flush() # redundant when followed by exit() 
    sys.exit(0) 

,而不是設置一個退出碼和exit()__main__名字空間荷蘭國際集團?

def respond_OK(): 
    global exit_status 
    sys.stdout.write('action=OK\n\n') 
    sys.stdout.flush() 
    exit_status = 0 

sys.exit(exit_status) 

從功能的角度來看,這種差異是微不足道的,只是想知道共識在形式上是什麼。如果你在別人的代碼中找到了先前的事物,你會看看它兩次嗎?

+4

很主觀的問題。在一個足夠小的應用程序(例如簡單的腳本)中,我可能不會在意。然而,把它放到一個大型的節目中,我會擔心到處都會退出。當然,這只是問「什麼是大型計劃」這個問題?一個主觀的問題值得另一個,我猜:P –

+0

我不明白爲什麼從任何地方調用'exit()'來調用任何其他函數是不好的形式。 – 2012-09-17 19:08:45

+3

有什麼不好的是:'globals()['exit_status'] = 0' Eww。 – FogleBird

回答

6

我希望看到從主入口點引發並處理的異常,其類型被轉換爲退出代碼。子類異常在python中非常簡單,它幾乎很有趣。

正如本答案的評論中所發表的那樣:使用sys.exit也意味着終止點需要知道實際的狀態碼,而不是遇到的那種錯誤。當然,這可以通過一組常數來解決。但是,使用異常還有其他優點:如果一種方法失敗,則可以嘗試另一種方法而無需重新輸入,或者打印一些事後調試信息。

+1

這正是'sys.exit' *做的*。它會引發[SystemExit](http://docs.python.org/library/exceptions.html#exceptions.SystemExit),它可以被捕獲或不被捕獲。好的一點是,如果你選擇讓解釋者在那個時候退出,它不會打印出一個醜陋的回溯。 – mgilson

+1

是的,但是終止點需要知道實際的狀態碼,而不是遇到的那種錯誤。當然,這可以通過一組常數來解決。但是,使用異常還有其他優點:如果一種方法失敗,則可以嘗試另一種方法而無需重新輸入,或者打印一些事後調試信息。 – sapht

+0

@sapht添加到您的答案。 – Marcin

3

它在功能上沒有什麼區別,但它可能會使你的代碼更難以遵循,除非你採取適當的步驟,例如,評論可能導致退出的主命名空間中的每個調用。

更新:注意@mgilson的答案重新捕捉異常的效果[可以捕獲system.exit引發的異常,從而阻止退出]。你可以讓你的代碼更加混亂。

更新2:注意@ sapht建議使用異常來編排出口。如果你真的想做一個非本地出口,這是一個很好的建議。比創建全球化要好得多。

3

有一些情況下,它是合理的慣用。

如果用戶給你錯誤的命令行參數,而不是這樣的:

def usage(arg0): 
    print ... % (arg0,) 
    return 2 

if __name__ == '__main__': 
    if ...: 
    sys.exit(usage(sys.argv[0])) 

你經常會看到這樣的:

def usage(): 
    print ... % (sys.argv[0],) 
    sys.exit(2) 

if __name__ == '__main__': 
    if ...: 
    usage() 

我能想到的是唯一的其他常見的情況下初始化某些庫(通過ctypes或低級別的C擴展模塊)意外失敗並將您置於無法推理的狀態,因此您只想儘快離開(例如,爲了減少出現違約或打印垃圾)例如:

if libfoo.initialize() != 0: 
    sys.exit(1) 

有人可能會反對,因爲sys.exit實際上並沒有真正從解釋器中釋放出來(拋出並捕獲異常),所以這是一種錯誤的安全感。但你仍然經常看到它。