python錯誤與異常處理

該筆記是根據(jù)慕課網(wǎng)中相關視頻學習記錄么库。
視頻地址:https://www.imooc.com/learn/457

錯誤和異常的概念

概念

錯誤的概念

  1. 語法錯誤:代碼不符合解釋器或者編譯器語法
  2. 邏輯錯誤:不完整或者不合法輸入或者計算出先問題

異常的概念

  1. 程序遇到邏輯或者算法問題
  2. 運行過程中計算機錯誤(內(nèi)存不夠或者IO錯誤)

區(qū)別

錯誤

  • 代碼運行前的語法或者邏輯錯誤
  • 語法錯誤在執(zhí)行前修改
  • 邏輯錯誤無法修改

異常

  1. 異常產(chǎn)生帖旨, 解釋器檢查到錯誤且認為是異常嚷炉,拋出異常
  2. 異常處理亡哄, 截獲異常融撞,忽略或者種植程序處理異常

常見的錯誤

  • 變量未賦值直接引用 錯誤信息為: NameError
  • 語法錯誤: SyntaxError
  • 打開不存在文件時 錯誤信息為:IOError
  • 算術運算除數(shù)為0時 錯誤信息為:ZeroDivision
  • 強制類型轉(zhuǎn)換時元數(shù)據(jù)不符合轉(zhuǎn)換規(guī)則 錯誤信息為:ValueError
  • 在IDE中使用 Ctrl+C 中斷程序執(zhí)行時 錯誤信息為:KeyboardInterupt

try-except 異常處理

代碼示例:

    try:
        print("測試代碼")
    except Exception e:
        print("異常處理代碼")
  1. try 用來捕獲 print("測試代碼") 中的異常烫堤,并且將異常就給except來處理
  2. except 用力啊處理異常悄晃,如果處理異常和設置捕獲異常 Exception 指向的一致,使用 print ("異常處理代碼") 來處理異常

try-except-else :處理多個異常

代碼示例

    try:
        f = open('1.txt', 'r')
        # 讀取兩個字節(jié)的內(nèi)容
        line = f.read(2)
        num = int(line)
        print("read the value is {}".format(num))
    except IOError e:
        print("catch IOError ", e)

    except ValueError e:
        print("catch ValueError ", e)

    else:
        print("it's fine, No Error")
  • 上述例子中會有兩個 bug 一個是文件不存在褥蚯,另一個是讀取的數(shù)據(jù)值(有字母)無法做 int() 強制轉(zhuǎn)換挚冤。
    所以通過兩個except捕獲異常
  • else 的作用是對無異常時的操作,看情況添加

try-finally語句

代碼示例:

    try:
        f = open('1.txt', 'r')
        res = int(f.read())
        print(res)
    finally:
        print("file close")
        f.close()

上述代碼執(zhí)行邏輯:

  • 當 try 中的代碼塊執(zhí)行無異常時赞庶,正常執(zhí)行結束后训挡,執(zhí)行 finally 中的代碼塊,打印信息和關閉文件歧强。
  • 當 try 中的代碼塊執(zhí)行有異常時澜薄,會先執(zhí)行finally中的內(nèi)容,打印信息和關閉文件摊册,同時返回異常信息給python解釋器肤京。

try-finally 執(zhí)行規(guī)則:

try-finally 無論是否會檢測到異常,都會執(zhí)行finally代碼茅特。

try-finally 語句作用:

為異常處理事件提供 清理機制忘分,用來關閉文件或者釋放系統(tǒng)資源。


try-except-finally

代碼示例:

    try: 
        f = open('1.txt', 'r')
        line = f.read(2)
        num = int(line)
        print("read num={}".format(num))
    except IOError e:
        print("catch IOError", e)
    except ValueError e:
        print("catch ValueError", e)
    finally:
        try:
            print("close file")
            f.close()
        except NameError e:
            print("catch NameError",e)

上述代碼執(zhí)行邏輯

try 中的代碼塊執(zhí)行打開文件温治,讀取文件中的2個字節(jié)信息饭庞,轉(zhuǎn)換為整型并打印出結果。

  • 若沒有出現(xiàn)異常熬荆,執(zhí)行玩try代碼塊之后舟山,執(zhí)行 finally 中的 try 代碼塊
  • 當出現(xiàn)異常時,先執(zhí)行異常的處理函數(shù),再執(zhí)行 finally 中的代碼塊累盗,再 finally 中也有對異常的處理寒矿,主要是在,文件為被正常打開的情況下若债,關閉會出現(xiàn)異常符相,故會執(zhí)行 finally-except 中的內(nèi)容

try-except-finally 執(zhí)行規(guī)則

  • 若 try 語句沒有捕獲異常,執(zhí)行完 try 代碼塊后蠢琳,執(zhí)行 finally 啊终。
  • 若 try 語句捕獲到異常,首先執(zhí)行except處理錯誤傲须,然后執(zhí)行 finally 蓝牲。

try-except-else-finally語句

語法格式

    try:
        try_suite
    except:
        do_except
    else:
        do_else
    finally:
        do_finally

try-except-else-finally執(zhí)行規(guī)則

  1. 若 try 語句沒有捕獲異常,執(zhí)行完 try 代碼塊后泰讽,執(zhí)行 else 代碼段例衍,最后執(zhí)行 finally
  2. 若 try 語句捕獲異常,首先執(zhí)行 except 處理錯誤已卸,然后執(zhí)行 finally

with……as語句

語法格式

    with context [as var]:
        with_suite
  1. with 語句用來代替 try-except-finally語句佛玄,使代碼更加簡潔;
  2. context 表達式返回的是一個對象,該對象需要支持上下文協(xié)議
  3. var 用來保存 context 返回的對象,支持單個返回值為變量港谊、多個返回值為元組類型
  4. with_suit 使用 var 變量來對 context 返回對象進行操作

with 語句示例

with open("1.txt","r") as f:
    for line in f.readlines():
        print(line)

示例解釋

  1. open("1.txt","r") 打開文件的操作會生成一個臨時的對象
  2. with open("1.txt","r") as f 表示將剛剛生成的臨時對象賦值給變量 f
  3. with 中的代碼執(zhí)行(無異常)完成時,會 自動關閉文件惑申,若 with 代碼塊有錯誤異常具伍,則不關閉文件翅雏,被報錯中斷,故需要使用 try-except 捕捉異常人芽。
  4. 對于上述的自動關閉功能可以使用 print(f.closed) 來驗證望几,結果為 True 表示已關閉,F(xiàn)alse 表示未關閉

with 語句實質(zhì)是上下文管理

  1. 上下文管理協(xié)議: 包含方法 enter() 和 exit() , 支持該協(xié)議的對象要實現(xiàn)這兩個方法
  2. 上下文管理器: 定義執(zhí)行 with 語句時要在建立 運行時上下文 萤厅,負責執(zhí)行 with 語句塊上下文中的進入退出操作
  3. 進入上下文管理器: 調(diào)用管理器 enter()方法橄抹,如果設置 as var 語句,var 變量接受 enter() 方法 返回值
  4. 退出上下文管理器: 調(diào)用管理器 exit 方法惕味,對資源進行清理楼誓,對文件進行關閉。

定義一個類學習上下文管理機制:

    class Mycontext(object):
        def __init__(self, name):
            self.name = name

        def __enter__(self):
            print("__enter__")
            return self
        
        def do_self(self):
            print("do_self")

        def __exit__(self, exc_type, exc_value, traceback):
            # exc_type 參數(shù)表示 錯誤類型
            # exc_value 參數(shù)表示 錯誤類型描述信息
            # traceback 參數(shù)表示 出錯的堆棧信息名挥,根據(jù)堆棧信息可以知道代碼是在哪一行出了錯誤
            print("__exit__")
            print("Error:", exc_type, "info:", exc_value)

    if __name__ == '__main__':
        with Mycontext("test_context") as f:
            print(f.name)
            f.do_self()

返回結果:

_enter_
test_context
do_self
_exit_
Error: None info: None

該執(zhí)行結果表明 with 語句會先執(zhí)行 _enter() 方法實例化一個對象疟羹,再 _init() 初始化對象, 再執(zhí)行相關操作,最后會執(zhí)行 _exit_() 操作,這是with語句規(guī)定的榄融。

針對上述例子的異常捕獲

    class Mycontext(object):
        def __init__(self, name):
            self.name = name

        def __enter__(self):
            print("__enter__")
            return self
        
        def do_self(self):
            print("do_self")
            a

        def __exit__(self, exc_type, exc_value, traceback):
            # exc_type 參數(shù)表示 錯誤類型
            # exc_value 參數(shù)表示 錯誤類型描述信息
            # traceback 參數(shù)表示 出錯的堆棧信息参淫,根據(jù)堆棧信息可以知道代碼是在哪一行出了錯誤
            print("__exit__")
            print("Error:", exc_type, "info:", exc_value)

    if __name__ == '__main__':
        with Mycontext("test_context") as f:
            print(f.name)
            f.do_self()

執(zhí)行結果

_enter_
test_context
do_self
_exit_
Error: <class 'NameError'> info: name 'a' is not defined
Traceback (most recent call last):
File "F:/脫產(chǎn)學習2017.10.27/兄弟連python/haolong/alice_code/demo/day7/test.py", line 27, in <module>
f.do_self()
File "F:/脫產(chǎn)學習2017.10.27/兄弟連python/haolong/alice_code/demo/day7/test.py", line 13, in do_self
a
NameError: name 'a' is not defined

該執(zhí)行結果表示代碼再執(zhí)行過程中出現(xiàn)在異常,會先執(zhí)行 _exit_()方法愧杯,再將異常拋出給python解釋器涎才。

應用場景

  1. 文件操作;
  2. 進程線程之間互斥對象力九,例如互斥鎖耍铜;
  3. 支持上下文的其他對象

raise 語句和 assert 語句

raise 語句
raise 語句用于主動拋出異常
語法格式: raise [exception[,args]]

  • exception: 異常類
  • args: 描述異常信息的字符串

assert 語句
斷言語句:assert語句用于檢測表達式是否為真,如果為假跌前,引發(fā) AssertionError 錯誤业扒;

語法格式:assert expression[,args]

  • expression: 表達式
  • args:判斷條件的描述信息,字符串

應用場景

定義函數(shù)或類中的方法舒萎,可以使用assert對傳入的參數(shù)進行格式判斷程储。在通過 try-except 對異常進行捕獲和處理


標準異常和自定義異常

標準異常:
標準異常:python 內(nèi)建異常,程序執(zhí)行前就已經(jīng)存在臂寝。

說明

  1. BaseException 類章鲤,所有異常都是繼承該類,若except中沒有指明異常的類型咆贬,則使用 BaseException 捕獲所有的異常
  2. KeyboardInterrupt 類是捕獲用戶使用 Ctrl + C 中斷程序?qū)е碌漠惓0芑玻苯永^承 BaseException 類
  3. Exception 類是系統(tǒng)、python解釋器異常的基類:
  • 該類繼承于 BaseException 類
  • 該類下還有 SyntaxError 類掏缎、NameError 類皱蹦、IOError 類、 ImportError 類等多個子類
  1. SystemExit 類是當 python 解釋器退出時觸發(fā)這個類眷蜈,出現(xiàn)異常
    對于不明白的類沪哺,建議訪問 python 官網(wǎng),查看詳細信息

自定義異常:

  1. python 允許自定義異常酌儒,用于描述 python 中沒有涉及的異常情況辜妓。
  2. 自定義異常必須繼承 Exception 類或者Exception 類下的子類
  3. 自定義異常只能主動觸發(fā) raise方法觸發(fā)

自定義異常示例:

  • 自定義異常:
  class FileError(IOError):
      pass
  • 產(chǎn)生自定義異常
  raise FileError, "file Error"
  • try-except 捕獲主動觸發(fā)的異常
  try:
      raise FileError, "file Error"  
  except FileError as e:
      print(e)
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市忌怎,隨后出現(xiàn)的幾起案子籍滴,更是在濱河造成了極大的恐慌,老刑警劉巖榴啸,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孽惰,死亡現(xiàn)場離奇詭異,居然都是意外死亡鸥印,警方通過查閱死者的電腦和手機勋功,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進店門腥例,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人酝润,你說我怎么就攤上這事燎竖。” “怎么了要销?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵构回,是天一觀的道長。 經(jīng)常有香客問我疏咐,道長纤掸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任浑塞,我火速辦了婚禮借跪,結果婚禮上,老公的妹妹穿的比我還像新娘酌壕。我一直安慰自己掏愁,他們只是感情好,可當我...
    茶點故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布卵牍。 她就那樣靜靜地躺著果港,像睡著了一般。 火紅的嫁衣襯著肌膚如雪糊昙。 梳的紋絲不亂的頭發(fā)上辛掠,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天,我揣著相機與錄音释牺,去河邊找鬼萝衩。 笑死,一個胖子當著我的面吹牛没咙,可吹牛的內(nèi)容都是我干的猩谊。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼镜撩,長吁一口氣:“原來是場噩夢啊……” “哼预柒!你這毒婦竟也來了队塘?” 一聲冷哼從身側響起袁梗,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎憔古,沒想到半個月后遮怜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡鸿市,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年锯梁,在試婚紗的時候發(fā)現(xiàn)自己被綠了即碗。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡陌凳,死狀恐怖剥懒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情合敦,我是刑警寧澤初橘,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布,位于F島的核電站充岛,受9級特大地震影響保檐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜崔梗,卻給世界環(huán)境...
    茶點故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一夜只、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蒜魄,春花似錦扔亥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至峦阁,卻和暖如春谦铃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背榔昔。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工驹闰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人撒会。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓嘹朗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诵肛。 傳聞我的和親對象是個殘疾皇子屹培,可洞房花燭夜當晚...
    茶點故事閱讀 43,576評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 一、簡介 Python最強大的結構之一就是它的異常處理能力怔檩,所有的標準異常都使用類來實現(xiàn)褪秀,都是基類Exceptio...
    隨風化作雨閱讀 3,066評論 0 1
  • 本文講解了python標準異常、什么是異常薛训、異常處理的多種方法和實例等內(nèi)容媒吗,需要的朋友可以參考下 python提供...
    小白python教程閱讀 1,252評論 0 2
  • ??選擇排序(Selection Sort)也是比較簡單的排序算法,思路也比較直觀乙埃。選擇排序算法在每一步中選取最小...
    一笑小先生閱讀 1,344評論 0 1
  • 關于應該過新歷生日還是農(nóng)歷生日闸英,我的觀點是應該過新歷生日锯岖,畢竟沒有閏月這一說,自然是準確些甫何。但是家里人的傳統(tǒng)...
    freecati閱讀 237評論 0 0
  • 好想回到那些年的春天 空氣中彌漫著春天的氣息 漫山遍野的紅花白花粉花 各種大自然的香味撲鼻而來 還有鳥兒嘰嘰喳喳的...
    為夢想而努力的蝸牛閱讀 126評論 0 0