2017-05-04 57 views
0

你在python中實現自己的異常類嗎?
現在,我還沒有遇到過我麻煩
沒有得到原有的局面。我的意思是,內置的Exception就足夠了。你在Python中實現自己的異常嗎?

自我實現異常的主要好處是什麼?

+0

與大多數語言不同,Python中的異常相對便宜,並且經常用作榮耀的GOTO--常常使用自定義異常來進行流量控制。 –

+0

有趣......「用於流量控制」意味着自定義異常有時用於非特殊情況? – Pythoner

+0

是的。最好的例子是'for'循環:當迭代器耗盡時,它會引發StopIteration。這根本不是特例,迭代器協議是該語言的核心。 –

回答

3

一般來說,你應該定義自己的異常的唯一時間是當你有一個特定的情況下提出一個自定義異常會比養現有Python異常更爲合適。

例如,說我正在執行的命令行參數解析API,我需要以考慮其中用戶輸入了一個無效的命令行參數,不管它可能是這種情況。現在,我可以簡單提高Python異常像SyntaxErrorNameError,但是這將是一個糟糕的設計決策。

我希望能夠傳達給用戶爲什麼引發異常,而不僅僅是引發異常。更好的選擇是將一般異常類Exception進行子類化,並創建特定的自定義異常。也許InvalidCommandLineArgument

現在,而不必使用一般的Python異常,我可以使用自定義異常,這有助於清楚和簡潔地告訴他們錯誤的用戶。

,如果你想在某個動作在你的代碼沒有被告知這也可以是有用的。例如,如果您創建了一個從互聯網下載certian文件的功能,它可能會引發異常,以便在互聯網連接關閉時通知您。這使您可以根據引發的異常情況採取特定的操作。

現在你可能想知道爲什麼在第二種情況下,你不能簡單地使用條件語句來測試是否有嘗試使用它之前的互聯網連接。你選擇後者與前者的原因是因爲Python的座右銘是「請求寬恕比請求許可更容易。」這基本上意味着,如果拋出異常,那麼請求Python捕獲異常比使用條件語句試圖繞過所有可能的錯誤更容易。

最後,它不是關於「你在Python中實現自己的異常?」,而是「你在Python中實現自己的異常?」

+0

非常感謝。現在我懂了。我們必須向用戶傳達爲什麼會引發異常,並且有時會根據異常的種類採取某種行動。另外,我在腦海中記住了這一點,「要求寬恕比要求許可容易」。 – Pythoner

+0

我很高興能幫助你更好地理解,@Daichi。您可能還有興趣閱讀[官方Python文檔]中有關例外的更多信息。(https://docs.python.org/3/library/exceptions.html) –

1

如果您想要捕捉您制定的特定類型的例外情況,這很有用。你永遠不想只抓住「例外」,因爲你可能會捕捉到你不瞭解的其他異常。

+0

雖然我明白你想說什麼,但我不認爲你說得很好。你沒有使用基本異常類的權利。你可能會掩蓋重要的錯誤。 _但是,你也不應該只是創建你自己的例外。如果Python已經提出錯誤,那麼您也嘗試創建自己的錯誤也沒有意義。這是多餘的。相反,找出您的代碼可能引發的確切錯誤,然後解釋這些具體的錯誤。 –

+0

我在想更多,這是避免意外錯誤導致代碼中出現錯誤的好方法。例如,如果您的代碼引發了ValueError並將其捕獲到別的地方,那麼您可能會錯過其他某個庫引發自己的ValueError的另一個地方。當然 - 在一個理想的世界中,你不會寫出拋出錯誤的代碼,但它不是一個理想的世界。 – Arya

1

自定義異常可以明確區分不同類型的錯誤。比較

class NumberTooBig(ValueError): 
    pass 

class NumberTooSmall(ValueError): 
    pass 

try: 
    ... 
except NumberTooBig: 
    ... 
except NumberTooSmall: 
    ... 

try: 
    ... 
except ValueError as exc: 
    if str(exc) == "too big": 
     ... 
    elif str(exc) == "too small": 
     ... 
    else: 
     # A different ValueError I don't know how to handle 
     raise exc 

有了自定義異常,您嵌入有關異常本身,這使得它更容易捕捉只有你想要的特定錯誤,而不必記住類型的錯誤信息重新提出您意外抓到的任何錯誤。

+0

感謝您展示具體的例子! – Pythoner

2

當您想將信息傳遞給調用您的代碼的其他人時,最好使用海關例外,以便他們可以確定要執行的操作。

例如:

比方說,我寫了一個模塊pet_store,其提供的get_dog(type)功能,你的說法。

當我寫的功能,有可能是某些方面,這可能會失敗:

NoDogsLeftException # Sold out of all dogs 
NoDogsOfBreedException # Sold out of that breed 
OwnerHouseCheckException # We checked your house and it's disgusting. Clean up you slob 

現在,當你import pet_storepet_store.get_dog("chihuahua"),我可能會拋出一個NoDogsOfBreedException ...因爲我不知道是什麼你想在這種情況下做。

有些人可能想嘗試另一種品種,如果只有奇瓦瓦人會滿足你,這是沒有意義的。如果我扔了OwnerHouseCheckException也不會有意義。如果我說你的房子對狗來說太髒了,那麼尋求不同的品種不會改變我的答案。但是,您可以採取足夠的信息採取行動。

這是事物的正確方法:讓誰喊你弄清楚也許你想要做什麼,如果發生異常

  • 重試
  • 嘗試不同查詢
  • 向用戶顯示一條消息
  • 啓動新服務器
  • 發射導彈
  • 發佈獵狗

的一點是:我不知道什麼是正確的事情是在你的程序。對你來說正確的事情可能與其他事情不同。相反,我會說:「這是出了什麼問題,做你想用這個信息做什麼。」

有些程序可能完全沒有互聯網接入(暗黑破壞神III),而其他程序可以處理離線(星際爭霸)。這些程序對NoInternetException會有不同的反應。

+0

該列表對我來說非常有幫助(而且很有趣)!謝謝。我總是隻顯示一條消息。現在我可以根據情況做更多的事情。 – Pythoner