[英]Raise exception vs. return None in functions?
在Python中的用戶定義函數中,更好的做法是: raise
異常或return None
? 例如,我有一個在文件夾中查找最新文件的函數。
def latestpdf(folder):
# list the files and sort them
try:
latest = files[-1]
except IndexError:
# Folder is empty.
return None # One possibility
raise FileNotFoundError() # Alternative
else:
return somefunc(latest) # In my case, somefunc parses the filename
另一個選擇是保留異常並在調用者代碼中處理它,但我認為處理FileNotFoundError
比IndexError
更清楚。 還是用其他名稱重新引發異常是不好的形式嗎?
這實際上是語義問題。 foo = latestpdf(d)
是什么意思 ?
沒有最新文件完全合理嗎? 然后確定,只返回None。
您是否希望總是找到最新文件? 引發異常。 是的,重新提出一個更合適的例外是可以的。
如果這只是應該應用於任何目錄的通用函數,我將做一個前一個並返回None。 如果該目錄是(例如)要成為包含應用程序已知文件集的特定數據目錄,則將引發異常。
在回答您的問題之前,我會提出一些建議,因為它可能會為您解答。
latestpdf
幾乎沒有什么意義,但查看您的函數latestpdf()
可獲得最新的pdf。 我建議您將其命名為getLatestPdfFromFolder(folder)
。 一旦我這樣做,就清楚應該返回什么內容。如果沒有pdf,則會引發異常。 但是,在那里等待更多..
for folder in folders:
try:
latest = getLatestPdfFromFolder(folder)
results = somefuc(latest)
except IOError: pass
希望這可以幫助!
我通常更喜歡在內部處理異常(即在被調用函數內部進行try / except,可能返回None),因為python是動態類型的。 總的來說,我認為這是一種判斷調用方式,但是在動態類型的語言中,有一些小因素會提示擴展規模,以免將異常傳遞給調用者:
if val is None
則比except ComplicatedCustomExceptionThatHadToBeImportedFromSomeNameSpace
。 嚴重的是,我討厭不得不記住from django.core.exceptions import ObjectDoesNotExist
鍵入內容from django.core.exceptions import ObjectDoesNotExist
在所有django文件的頂部都from django.core.exceptions import ObjectDoesNotExist
只是為了處理一個非常普通的用例。 在靜態類型的世界中,讓編輯器為您完成。 不過,老實說,它始終是一個判斷調用,而您所描述的情況(被調用函數收到它無法幫助的錯誤)是重新引發有意義的異常的極好理由。 您有完全正確的想法,但除非有例外,否則您將在堆棧跟蹤中提供比
AttributeError: 'NoneType' object has no attribute 'foo'
如果您返回未處理的None(無),則打擾者將看到呼叫的結果,十分之九。
(所有這些使我希望python異常在默認情況下具有cause
屬性,就像在Java中一樣,它使您可以將異常傳遞到新的異常中,以便您可以拋棄所有想要的問題,而不會丟失問題的原始源。
一般來說,如果發生了無法恢復的災難性事件(即,您的函數處理了無法連接的某些互聯網資源),則應該拋出異常;如果函數確實返回了某些內容,則應返回None。但沒有合適的返回值(例如,如果您的函數嘗試匹配字符串中的子字符串,則為“ None”)。
使用python 3.5的輸入 :
返回None時的示例函數為:
def latestpdf(folder: str) -> Union[str, None]
並且在引發異常時將是:
def latestpdf(folder: str) -> str
選項2似乎更具可讀性和pythonic
(+選項,如前所述,為異常添加注釋。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.