週末多碼文,昨天晚上一篇,今天再來一篇:html
在線編程:https://mybinder.org/v2/gh/lotapp/BaseCode/masterpython
在線預覽:http://github.lesschina.com/python/base/oop/3.異常相關.htmlgit
代碼褲子:https://github.com/lotapp/BaseCode/tree/master/python/2.OOP/4.Exception程序員
又到了開新課的時候了,小明同窗此次提早預習了知識,乘着老師還沒來就在黑板上寫下了這段Code:github
def main():
try:
1 / 0 # ZeroDivisionError: division by zero
except ZeroDivisionError as ex:
print(ex)
if __name__ == '__main__':
main()
小潘同窗剛進來就看見了,自語道:「try...except
捕獲異常誰不會?就會這麼屁點東西還好意思秀,切~ 我給你把 格式補全」編程
因而乘着小明上廁所的時候,擦掉小明的Code,本身寫了一段高大上的Code:app
# 異常捕獲全格式
def test(input_str):
try:
eval(input_str)
except ZeroDivisionError as ex:
print("except:", ex)
else:
print("else:沒有異常就獎勵100塊~")
finally:
print("finally:小明是傻子~")
def main():
test("1/0")
print("-" * 10)
test("print('小明啊小明你調坑裏了~')")
if __name__ == '__main__':
main()
這時候小明和老師一塊兒進來了,同窗們隱約間都聽到小明的自詡聲:「老師,我可好了,提早預習而且還寫了個demo在黑板上呢~」less
老師一進門看着黑板就笑了,同窗們也笑成一片。小明心想,咦~難道我寫錯了?定眼一看黑板,氣呼呼的回座位了編輯器
else
能夠不寫,不過咱們 基本上仍是會寫的,畢竟能夠知道是真的沒有錯誤,而不是屏蔽了錯誤oop
老師很欣慰,以爲這個班真有意思,你們學習空前熱情,爲了照顧小明,老師反問道:「有誰知道 多個異常怎麼處理?」
小明飛快的舉手並把黑板上內容擦完,寫下了以下代碼:
# 多個異常捕獲
def main():
try:
print(xiaopan) # NameError: name 'xiaopan' is not defined
1 / 0 # ZeroDivisionError: division by zero
except NameError as ex:
print(ex)
except ZeroDivisionError as ex:
print(ex)
if __name__ == '__main__':
main()
老師問了小明一聲,有幾個輸出?
小明驕傲的說道:「兩個,我寫了兩個異常處理,固然都執行了」
同窗們又笑了,小潘調侃的說了句:「一看就知道去年C#沒好好學,這不都同樣嘛,遇到異常下面代碼還執行嗎?用腦子好好想一想」
當咱們認爲某些代碼可能會出錯時,就能夠用try
來運行這段代碼,若是執行出錯,則後續代碼不會繼續執行,而是直接跳轉至except
語句塊,執行完except
後,若是有finally
語句塊,則執行finally語句塊
小明又尷尬了。。。
老師再次幫小明圓了個場:「已經很不簡單了,就是最後小得意的時候口誤了,那小明同窗你知道Python裏面多異常有個便捷寫法嗎?」
小明趕忙拿起粉筆刷刷刷的寫完,而後說道:「of course」
# 多個異常捕獲的簡寫(注意哦,是元組哦)
def main():
try:
print(xiaopan) # NameError: name 'xiaopan' is not defined
1 / 0 # ZeroDivisionError: division by zero
except (NameError, ZeroDivisionError) as ex:
print(ex)
if __name__ == '__main__':
main()
老師趕忙誇了誇小明,心想,哎呦喂終於把這難纏的傢伙弄回座位了。
小明走前還不忘說一句:「簡寫的時候注意格式哦,是 元組 不是逗號分隔」
老師這堂課很輕鬆,你們都預習了並且內容也比較簡單。
接着以提問的方式問道:「小潘同窗,你知道異常的基類是什麼嗎?若是要捕獲全部異常該怎麼作呢?」
小潘站起來講道:「是BaseException
」
老師擴充道:「全部的錯誤類型都繼承自BaseException
,因此在使用except
時須要注意的是,它不但捕獲該類型的錯誤,還把其子類也一塊兒捕獲了」
因此通常在捕獲異常的時候 把子類異常放在前面,父類放在後面
看以下代碼:
def main():
try:
1 / 0 # ZeroDivisionError: division by zero
except BaseException as ex:
print("base:", ex)
except ZeroDivisionError as ex:
print(ex)
if __name__ == '__main__':
main()
若是把父類放第一個,那麼ZeroDivisionError
永遠也不會被執行了,其實你若是裝了 代碼規範提示插件會提示你的
能夠參考我以前寫的 vscode設置python3調試環境的擴充部分
來個通用異常捕獲的簡寫(官方不推薦使用簡寫):
# 直接except就好了
def main():
try:
1 / 0
dnt += 1
except:
print("屏蔽錯誤")
if __name__ == '__main__':
main()
老師繼續講到,咱們來看一個場景,如今不少在線編輯器,你在他們那些編輯框裏寫下了代碼也是有異常拋出的,這是怎麼處理的呢?
微軟有開源代碼編輯器比較受歡迎(VSCode的一部分):monaco-editor
提示一下,若是真的要作在線編輯器,記得考慮一下fork炸彈
,這個其實也是很老的東西了,程序員基本上都應該接觸過了
咱們繼續,像C#是用thorw
拋出異常,那Python怎麼 捕獲異常後再拋出
呢?怎麼自定義異常
呢?
繼續往下看:
# 捕獲異常後再丟出,eg:在線運行的用戶Code
def main():
try:
1 / 0 # ZeroDivisionError: division by zero
except ZeroDivisionError as ex:
print(ex) # 寫個日誌,回頭出問題能夠深究
raise
if __name__ == '__main__':
main()
# 拋出自定義異常
class DntException(BaseException):
pass
def get_age(num):
if num <= 0:
raise DntException("num must>0")
else:
print(num)
def main():
get_age(-1)
get_age(22) # 程序崩了,這句話不會被執行了
if __name__ == '__main__':
main()
異常這一塊基本上講完了(logging
模塊後面會說)有什麼補充的能夠說的^_^
小明又進行了C#的代碼轉換,怎麼看都以爲仍是C#簡單啊,根本不用說啥,代碼一貼就秒懂了。。。
%%script csharp
try
{
Convert.ToInt32("mmd");
}
catch (Exception ex)
{
// Input string was not in a correct format
Console.WriteLine(ex.Message);
}
%%script csharp
//拋出自定義異常
try
{
throw new Exception("出錯了啊");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
你能夠自定義異常類,繼承Exception便可,對了C#裏面也是有finally的
try
{
throw new Exception("出錯了啊");
//Convert.ToInt32("mmd");
}
catch (Exception ex)
{
// Input string was not in a correct format
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("finally");
}
如今一些須要finally的地方基本上都被using(){}接管了,因此特定場景會使用
先這樣了