python錯誤與異常處理

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

錯誤和異常的概念

概念

錯誤的概念

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

異常的概念

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

區(qū)別

錯誤

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

異常

  1. 異常產(chǎn)生, 解釋器檢查到錯誤且認(rèn)為是異常,拋出異常
  2. 異常處理, 截獲異常,忽略或者種植程序處理異常

常見的錯誤

  • 變量未賦值直接引用 錯誤信息為: NameError
  • 語法錯誤: SyntaxError
  • 打開不存在文件時 錯誤信息為:IOError
  • 算術(shù)運(yùn)算除數(shù)為0時 錯誤信息為:ZeroDivision
  • 強(qiáng)制類型轉(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 用力啊處理異常,如果處理異常和設(shè)置捕獲異常 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() 強(qiáng)制轉(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í)行邏輯:

  • 當(dāng) try 中的代碼塊執(zhí)行無異常時,正常執(zhí)行結(jié)束后,執(zhí)行 finally 中的代碼塊,打印信息和關(guān)閉文件。
  • 當(dāng) try 中的代碼塊執(zhí)行有異常時,會先執(zhí)行finally中的內(nèi)容,打印信息和關(guān)閉文件,同時返回異常信息給python解釋器。

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

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

try-finally 語句作用:

為異常處理事件提供 清理機(jī)制,用來關(guān)閉文件或者釋放系統(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)換為整型并打印出結(jié)果。

  • 若沒有出現(xiàn)異常,執(zhí)行玩try代碼塊之后,執(zhí)行 finally 中的 try 代碼塊
  • 當(dāng)出現(xiàn)異常時,先執(zhí)行異常的處理函數(shù),再執(zhí)行 finally 中的代碼塊,再 finally 中也有對異常的處理,主要是在,文件為被正常打開的情況下,關(guān)閉會出現(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 表達(dá)式返回的是一個對象,該對象需要支持上下文協(xié)議
  3. var 用來保存 context 返回的對象,支持單個返回值為變量、多個返回值為元組類型
  4. with_suit 使用 var 變量來對 context 返回對象進(jìn)行操作

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í)行(無異常)完成時,會 自動關(guān)閉文件,若 with 代碼塊有錯誤異常,則不關(guān)閉文件,被報錯中斷,故需要使用 try-except 捕捉異常。
  4. 對于上述的自動關(guān)閉功能可以使用 print(f.closed) 來驗(yàn)證,結(jié)果為 True 表示已關(guān)閉,F(xiàn)alse 表示未關(guān)閉

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

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

定義一個類學(xué)習(xí)上下文管理機(jī)制:

    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()

返回結(jié)果:

_enter_
test_context
do_self
_exit_
Error: None info: None

該執(zhí)行結(jié)果表明 with 語句會先執(zhí)行 _enter() 方法實(shí)例化一個對象,再 _init() 初始化對象, 再執(zhí)行相關(guān)操作,最后會執(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í)行結(jié)果

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

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

應(yīng)用場景

  1. 文件操作;
  2. 進(jìn)程線程之間互斥對象,例如互斥鎖;
  3. 支持上下文的其他對象

raise 語句和 assert 語句

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

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

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

語法格式:assert expression[,args]

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

應(yīng)用場景

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


標(biāo)準(zhǔn)異常和自定義異常

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

說明

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

自定義異常:

  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)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、簡介 Python最強(qiáng)大的結(jié)構(gòu)之一就是它的異常處理能力,所有的標(biāo)準(zhǔn)異常都使用類來實(shí)現(xiàn),都是基類Exceptio...
    隨風(fēng)化作雨閱讀 3,147評論 0 1
  • 本文講解了python標(biāo)準(zhǔn)異常、什么是異常、異常處理的多種方法和實(shí)例等內(nèi)容,需要的朋友可以參考下 python提供...
    小白python教程閱讀 1,306評論 0 2
  • ??選擇排序(Selection Sort)也是比較簡單的排序算法,思路也比較直觀。選擇排序算法在每一步中選取最小...
    一笑小先生閱讀 1,466評論 0 1
  • 關(guān)于應(yīng)該過新歷生日還是農(nóng)歷生日,我的觀點(diǎn)是應(yīng)該過新歷生日,畢竟沒有閏月這一說,自然是準(zhǔn)確些。但是家里人的傳統(tǒng)...
    freecati閱讀 306評論 0 0
  • 好想回到那些年的春天 空氣中彌漫著春天的氣息 漫山遍野的紅花白花粉花 各種大自然的香味撲鼻而來 還有鳥兒嘰嘰喳喳的...
    為夢想而努力的蝸牛閱讀 173評論 0 0

友情鏈接更多精彩內(nèi)容