干貨來了!阿里工程師告訴你Python中異常處理的常用方法總結(jié)
如果你想選擇一種語言來入門編程,那么Python絕對是***!
其非常接近自然語言,精簡了很多不必要的分號和括號,非常容易閱讀理解。編程簡單直接,更適合初學(xué)編程者,讓其專注于編程邏輯,而不是困惑于晦澀的語法細(xì)節(jié)上,比起JAVA、C#和C/C++這些編程語言相對容易很多。
因此,即使是非計(jì)算機(jī)專業(yè)或者沒有基礎(chǔ)的小白,也能分分鐘入門。Python的排名從去年開始就借助人工智能持續(xù)上升,現(xiàn)在它已經(jīng)成為了***名。
今天小編和小伙伴們分享一下異常處理的這個常用的解決方法。異常處理在任何一門編程語言里都是值得關(guān)注的一個話題,良好的異常處理可以讓你的程序更加健壯,清晰的錯誤信息更能幫助你快速修復(fù)問題。在Python中,和不分高級語言一樣,使用了try/except/finally語句塊來處理異常,如果你有其他編程語言的經(jīng)驗(yàn),實(shí)踐起來并不難。
什么是例外?
1.錯誤
就軟件而言,錯誤是合乎邏輯的或合乎邏輯的。錯誤是合乎邏輯的或合乎邏輯的。
語法錯誤表明,軟件的結(jié)構(gòu)中存在錯誤,無法由解釋器解釋,也不能編譯編譯器。這些錯誤必須在程序執(zhí)行前更正。
當(dāng)程序的語法正確時,剩下的就是邏輯錯誤。邏輯錯誤可能是由于不完整或非法輸入引起的;
在其他情況下,可能無法執(zhí)行邏輯不能生成、計(jì)算或輸出結(jié)果的過程。這些錯誤通常被稱為域錯誤和范圍錯誤。
當(dāng)Python檢測到錯誤時,Python解釋器指出當(dāng)前流無法繼續(xù)。這時有一種反?,F(xiàn)象。
2.異常
對異常的***描述是因?yàn)槌绦蝈e誤,在正??刂屏髦庑袨椤?/p>
這種行為分為兩個階段:***個是導(dǎo)致異常發(fā)生的錯誤,然后是檢測(和可能的措施)階段。
***階段發(fā)生在異常情況(有時稱為異常)之后。
只要檢測到錯誤并實(shí)現(xiàn)異常條件,解釋器中就會出現(xiàn)異常。觸發(fā)器也可以稱為觸發(fā)器,拋出或生成。解釋器通知當(dāng)前控制流有錯誤。
Python還允許程序員為自己創(chuàng)建異常。無論是Python解釋器還是程序員,異常都是錯誤的信號。
將中斷當(dāng)前流以處理此錯誤并采取相應(yīng)操作。這是第二階段。
異常處理發(fā)生在第二階段,在異常發(fā)生后,可以調(diào)用許多不同的操作。
您可以忽略錯誤(記錄錯誤,但不采取任何措施,采取補(bǔ)救措施并終止程序)。或者試著在減少問題的影響后繼續(xù)這個過程。
所有這些操作都代表一個延續(xù),或者一個控制分支。關(guān)鍵是程序員可以在錯誤發(fā)生時指示程序是如何執(zhí)行的。
Python使用異常對象(異常對象)來表示異常。遇到錯誤時會出現(xiàn)例外情況。
如果異常對象沒有被處理或捕獲,程序?qū)⒔K止執(zhí)行,即所謂回溯(回溯)。
異常處理
語句可以用來捕獲異常。
試用語句用于檢測嘗試語句塊中的錯誤,以便除了語句可以捕獲異常信息并處理它。
如果您不希望在異常時終止程序,請?jiān)趪L試中捕獲它。
Grammar:
下面是嘗試的簡單語法……除了…其他的:
嘗試的工作原理是,在開始嘗試語句時,Python被標(biāo)記在當(dāng)前程序的上下文中,這樣當(dāng)出現(xiàn)異常時,它可以返回這里。嘗試子句首先執(zhí)行,接下來會發(fā)生什么取決于執(zhí)行中是否有異常。
-
如果在執(zhí)行語句后執(zhí)行異常,則Python會跳回去嘗試并執(zhí)行與異常匹配的***個除外子句。在處理異常之后,控制流將通過整個嘗試語句(除非在處理異常時出現(xiàn)新異常)。
-
如果在嘗試后語句中有一個異常,但是除了子句沒有匹配,異常將被發(fā)送到上一個嘗試或程序的頂部,這將結(jié)束程序并打印默認(rèn)的錯誤消息。
-
如果在嘗試子句的執(zhí)行中沒有例外,Python將在其他語句之后執(zhí)行語句(如果有其他的話),然后通過整個嘗試語句控制流。
使用except而不帶任何異常類型
除例外類型外,您可以使用,如下所示:
上面的嘗試除了語句捕獲所有已經(jīng)發(fā)生的異常。但這不是通過程序識別特定異常信息的好方法。因?yàn)樗东@了所有異常。
使用except而帶多種異常類型
您還可以使用同一個語句來處理多個異常信息,如下所示:
try-finally 語句
***一個語句執(zhí)行***一個代碼,不管是否有異常。
當(dāng)一個異常被拋出嘗試塊時,***塊代碼立即執(zhí)行。
在***一個塊中的所有語句執(zhí)行后,再次觸發(fā)異常,執(zhí)行除塊代碼之外的執(zhí)行。
參數(shù)的內(nèi)容與異常不同。
下面舉個例子:
總結(jié)如下:
-
除了陳述之外,沒有必要,***的陳述是沒有必要的,但兩個必須有一個,否則沒有嘗試的意義。
-
除了聲明之外,還有不止一種說法。Python將按照除語句外的順序匹配指定的異常。如果處理異常,則稍后將不進(jìn)入該例外聲明。
-
除了語句可以以元組的形式以元組的形式指定多個異常,還可以看到實(shí)例代碼。
-
如果在例外語句之后沒有指定異常類型,默認(rèn)情況下會捕獲所有異常,并且可以通過日志記錄或sys模塊獲取當(dāng)前異常。
-
如果你想捕獲一個異常來重復(fù)它,請使用“上升”,不要帶任何參數(shù)或信息在它后面。
-
不建議捕獲和拋出相同的異常。考慮重構(gòu)代碼。
-
不建議在邏輯不明確的情況下捕獲所有異常,并且可能隱藏了一個非常嚴(yán)重的問題。
-
試著更換嘗試/除了內(nèi)置的異常處理語句的語句,如與聲明的getattr()方法。
實(shí)證案例
傳遞異常重新引發(fā)異常
在python2,為了保持異常的完整信息,你不能在添加例外對象提高當(dāng)你抓住它了,否則你的跟蹤信息將從這里切斷。以上是重新拋出異常的最簡單方法。
還可以考慮一些其他技術(shù),例如在拋出異常之前更新異常信息。
Python3提高了重復(fù)傳輸?shù)睦?,你可以自己試試,但建議同。
Exception 和 BaseException
當(dāng)我們想要捕捉的一般例外,我們應(yīng)該使用異?;騜aseexception?我建議你看看官方文件,這兩個例外有什么區(qū)別?請看他們之間的繼承權(quán)。
從異常的層次結(jié)構(gòu),baseexception是最基本的異常類繼承它,和異常。除了所有的例外,baseexception包含三systemexit例外,keyboardinterrupt和generatorexit。
看來,你的程序應(yīng)該使用異常而不是baseexception當(dāng)捕獲所有異常,因?yàn)槠渌齻€例外,屬于高層次的例外,和合理的方式應(yīng)該是Python解釋器處理。
except Exception as e和 except Exception, e
代碼示例如下所示:
在python2時代,你可以使用任何寫作的上述兩種風(fēng)格。在Python3,你只能使用寫作***的風(fēng)格,和第二形式被遺棄。***種文字可讀性更好,為了程序的兼容性和后期移植的成本,你也留下了第二種寫作方式。
raise “Exception string”
將字符串作為異常拋出似乎是非常簡單的方法,但這是一個非常壞的習(xí)慣。
如果上面的語句被拋出異常,它將是這樣的。
這是可接受的在python2.4,但沒有指定異常類型,它可能使正確捕獲和處理異常的下游,導(dǎo)致你的程序被掛起??傊?,這種文體是封建時代的不良習(xí)慣,應(yīng)該扔掉。
使用內(nèi)置的語法范式代替try/except
Python本身提供了許多語法范式,簡化處理異常,如StopIteration異常處理的語句,讓你寫一個循環(huán)順暢。
在打開文件之后,帶語句自動調(diào)用關(guān)閉的文件操作。當(dāng)我們編寫Python代碼時,當(dāng)遇到這種情況時,我們應(yīng)該避免嘗試/排除/***考慮。
例如,當(dāng)我們需要訪問一個不確定的屬性時,您可能會編寫這樣的代碼:
事實(shí)上,你可以使用一個更簡單的getattr()來實(shí)現(xiàn)你的目標(biāo)。
***實(shí)踐
***的做法不限于編程語言,而只限于一些規(guī)則,并在填充之后收獲。
1.例外,您知道,避免捕捉所有異常并吞噬它們。
2.拋出的異常應(yīng)該解釋為什么,有時您知道異常類型不能被猜測。
3.避免在catch語句塊中做一些毫無意義的事情。
4.不要使用異常來控制進(jìn)程,這樣您的程序就很難理解和維護(hù)。
5.如果有需要,記得使用***釋放資源。
6.如果您需要它,在處理異常后不要忘記清理或回滾。
異常的查找表