2013-07-11 115 views
1

所以最近我一直在問Python關於更多專業和pythonic風格的問題,儘管我的問題給出了很好的答案,但我覺得我需要提出一個更廣泛的問題。通常,在編寫處理副作用(文件寫入,字典定義等)而不是返回值的效用函數(對於庫等)時,返回狀態代碼以告訴調用它通過或失敗的函數。Python返回代碼

在Python,似乎有三種方式來標記此:

使用的-1或0(C等)的返回值,並使用語句如

if my_function(args) < 0: 
    fail condition 
pass condition 

,或者使用一回真值/假

if not my_function(args): 
    fail condition 
pass condition 

,或者使用「回報或‘返回None’使用異常(未知錯誤退出)

try: 
    my_function(args) 
except ExpectedOrKnownExceptionOrError: 
    fail condition 
pass condition 

哪個最好?最正確的?首選?我理解所有的工作,並且沒有太多的技術優勢(除了可能的異常處理的開銷)。

回答

7

不要返回指示錯誤的東西。拋出一個異常。絕對不要捕捉異常並將其轉換爲返回碼。

+0

+1,這樣做會很... C++。 – 2rs2ts

+0

是的,這是EAFP的方法,在Python中很常見。類似C的方法在這裏可能是最糟糕的,但最終,這一切都取決於圖書館的確切目標,以及在常見用法方面更一致。 – Tadeck

+0

好的,這是我的問題。如果我的論點不符合功能要求,我應該只是拋出一個基本的異常?像 如果數據<0: 引發異常('bad input') –

1

當發生異常而未捕獲時,Python will exit with an error (non-zero) code for you。如果您正在定義自己的例外類型,則應該使用override sys.excepthook()爲您提供所需的退出代碼,因爲它們默認使用退出代碼1

如果由於某種奇怪的原因想要指定退出代碼,請使用sys.exit()errno模塊獲取標準退出代碼,以便使用適當的退出代碼。您也可以使用traceback模塊獲取堆棧回溯(根據該答案,它似乎也是正確的錯誤代碼)。就我個人而言,我也不喜歡這種方法。

我推薦的方法是不是發現異常;讓它發生。如果你的程序在異常發生後可以繼續運行,你應該抓住它並適當地處理它。但是,如果你的程序無法繼續,你應該讓例外。這對於在其他Python模塊中重新使用你的程序特別有用,因爲如果你願意的話,你將能夠捕捉到異常。

1

很像其他的一切:這取決於。

例外情況對於將本地例程(或其調用者 - 見下文)無法處理或預期處理的錯誤或條件的錯誤或條件「傳遞給」鏈條有很好的作用。特別是如果「誰」可以處理它位於調用堆棧的幾個層次。我認爲這是例外情況的「最佳」使用。

異常的不利之處在於,一旦發生異常,即使問題得到解決,也不會再回到原來的位置。你必須從頭開始重新開始例程。

返回值適用於預期不會「意外」失敗的例行操作。檢查返回值並從那裏開始。它們對於本地例行程序可以從中恢復的問題也很有用。例如,如果例程預計在放棄之前嘗試了3次,返回通過/失敗/真/假可能是合適的。

根據我的經驗,期待調用者處理來自其被調用者的返回值和異常都只是乏味。在我看來,在Try/Except塊中檢查返回值只會造成笨拙的邏輯...至少對於我所做的工作而言。

這並不是說您不能使用異常而不是的返回值。確實有可以提供更簡潔的代碼的情況。

我的妥協方法是試圖限制自己在單個例程中返回值或例外。我嘗試限制我的呼叫者需要檢查的內容。

當我需要這兩個,我嘗試限制我的使用異常問題,我的直接調用者無法處理。換句話說,我的直接調用者會期望得到一個真/假/無論返回值,但預計也不會處理異常。例外情況可能由,他們的調用者等來處理。當在同一例程中使用兩者時,我試圖將我的例外限制爲真正的「例外」(即不常見的問題)。

此外,首選的Python成語是使用True/False而不是1/0。除非你用C語言編寫,否則你要在你的Linux腳本中返回一個Linux退出代碼。