1. 程式人生 > >Python基礎總結之異常、除錯程式碼第十二天開始(新手可相互督促)

Python基礎總結之異常、除錯程式碼第十二天開始(新手可相互督促)

年薪20萬的夢想,加油!

       我們在寫程式碼的時候,控制檯經常會報錯,因為某種錯誤,導致我們的程式停止,且不再執行下面的程式碼。

我們看一個錯誤的程式碼示例:

 

def add_1():     #沒有引數
print('我出錯了') #不會被執行

def add_2(): #函式二呼叫函式一
print('第二個函式呼叫函式一,並給他一個引數')
add_1(4) #函式一沒有引數,所以有會報異常,並終止,不會執行函式一里面的程式碼

def add_3(): #函式三呼叫函式二
add_2()

d = add_3() #呼叫函式三

        看完截圖,可以理解在函式呼叫的路徑中,控制檯顯示的呼叫過程很清晰,這個過程就是函式呼叫棧的概念,它可以直接找到出錯的地方。因為定義的函式add_1,不需要任何引數。

        但是在呼叫的時候傳入了一個引數值4,所以導致了程式停止,函式add_1裡面的print語句沒有被執行。

當我們在控制檯看到Traceback出現,就說明程式有異常出現,異常就是最下面的TypeError。它只是異常的一種,如果我們沒有對異常進行捕獲處理,程式就會停止,且後面的程式碼都不會再執行。

       我們可以使用   try...except...finally...  這樣的方法來捕獲異常,和處理異常。

 1 def add_1():     #不需要傳入引數
 2     print('我出錯了')        #不會被執行
 3 
 4 def add_2():           #函式二呼叫函式以
 5     print('第二個函式呼叫函式一,並給他一個引數')
 6     try:
 7         add_1(4)       #我們知道在這裡,傳參的時候會導致錯誤,所以我們在這裡捕獲異常。
 8     except :     #except 後面不新增任何錯誤型別,表示捕獲所以異常型別。再不知道是什麼型別的異常,導致程式停止,可以用它來處理。
 9         print('捕獲了所有異常,不論什麼異常導致')
10 
11 def add_3():
12     add_2()
13 d = add_3()       #呼叫函式三

當我們不知道哪裡異常的時候,我們可以將try...except...的範圍先放大,然後慢慢縮小。

1 try:
2     a = ['a','b',1,2]    #建立一個列表,變數是a,指向列表
3 
4     print(c)        #打印出錯變數c,會出現一個未宣告物件的錯誤:NameError,程式碼中的變數c並沒有指向任何物件
5 except TypeError:   #TypeError是型別異常的錯誤,我們捕獲的異常和程式出現的異常不一致,所以捕獲是不成功的
6     print('捕獲異常')

從圖中發現我們捕獲的異常和出現的異常不一致,所以異常的捕獲是失效的,python 中有很多異常型別,如果不指定用哪個型別的異常捕獲,那麼就直接用案例一的方法,捕獲所有異常,我們可以這樣實現程式碼:

except Exception:     也可以直接寫成   except:  不加後面的Exception,也代表捕獲所有的異常,兩種格式。

1 try:
2     a = ['a','b',1,2]    #建立一個列表
3 
4     print(c)        #打印出錯變數c,會出現一個未宣告物件的錯誤:NameError,因為列表的變數是a
5 except Exception:   #Exception,代表捕獲所有型別的異常
6     print('捕獲所有型別的異常')

 

        如果我們程式執行到這裡的時候,我們知道一般會出現哪幾種情況,我們可以連續使用幾個except程式碼塊兒,分別捕獲不同的異常。當執異常產生了,並且出現的異常型別是我們捕獲的except程式碼塊兒中的一個型別,那麼所捕獲的錯誤型別就會執行相應的程式碼,而不是對應的該異常的程式碼塊,因為捕獲的異常型別不匹配,所以它們對應的程式碼不會被執行。

1 try:
2     a = ['a','b',1,2]    #建立一個列表
3 
4     print(c)        #打印出錯變數c,會出現一個未宣告物件的異常報錯:NameError,因為列表的變數是a
5 
6 except TypeError:
7     print('捕獲 TypeError 型別異常')
8 except NameError:   #捕獲NameError型別異常
9     print('捕獲 NameError 型別異常')

       我們知道了程式碼停止執行的異常型別,我們才能根據異常的型別去修改除錯我們的程式碼。接下來我們再看看finally語句。finally語句,不管是否有異常,我們都有執行一段程式碼,比如,即使讀取檔案出現異常,那麼我們也要執行後面的程式碼,那麼我們就可以用finally這個關鍵字實現。

 1 import os                                   #匯入os模組
 2 try:
 3     os.chdir(r'C:\Program Files\tools')         #切換到指定的路徑目錄
 4     print(os.listdir(os.getcwd()))
 5 
 6     file_1= open(r'C:\Program Files\tools\ffff.txt')   #我們的目錄中沒有ffff.txt檔案
 7 
 8 except FileNotFoundError:                             #捕獲未找到檔案的異常報錯
 9     print('未找到檔案 FileNotFoundError')
10 
11 finally:                                             #但是下面的程式碼我們還是想執行
12     print('為了證明執行力finally的程式碼')

捕獲異常的初級使用方法大概就是這樣捕獲了。下面附上常見的異常型別, 多多敲擊程式碼,出錯後要嘗試根據錯誤的提示,去修改程式碼,這也是一種成長~~~~~

 

    1.AssertionError:當assert斷言條件為假的時候丟擲的異常

  2.AttributeError:當訪問的物件屬性不存在的時候丟擲的異常

  3.IndexError:超出物件索引的範圍時丟擲的異常

  4.KeyError:在字典中查詢一個不存在的key丟擲的異常

  5.NameError:訪問一個不存在的變數時丟擲的異常

  6.OSError:作業系統產生的異常

  7.SyntaxError:語法錯誤時會丟擲此異常

  8.TypeError:型別錯誤,通常是不通型別之間的操作會出現此異常

  9.ZeroDivisionError:進行數學運算時除數為0時會出現此異常

&n