Python基礎 -- 異常處理

excellentFish發表於2024-05-07

try-except

寫程式碼過程中難免會出現異常,比如:

執行 a=10/0 時會提示:ZeroDivisionError: division by zero
直接執行 a 會提示: NameError: name 'a' is not defined
執行 import mokuai (模組庫中沒有的模組) 會提示: ModuleNotFoundError: No module named 'mokuai'

這些錯誤型別如ZeroDivisionError、NameError、ModuleNotFoundError等都是繼承自Python標準庫裡的Exception類中的異常物件類,而程式在執行過程中報出這些錯誤時會影響程式後續的執行,如果不想因為這裡發生錯誤導致影響程式後續執行則需要使用try...except... 來捕獲和處理異常,如下所示

try:
    100/0
except ZeroDivisionError as e:
    print (f'異常物件資訊:{e}')

但是這是在明知會發生ZeroDivisionError的情況下做的處理,如果不知道會出現什麼型別的錯誤,並且希望無論發生什麼錯誤也不要影響程式的後續執行,則需要匹配全型別的異常,如下所示:

try:
    100/0
except Exception as e:
    print (f'異常物件資訊:{e}')

除此之外還可以去自定義錯誤型別:

# 自定義“小黑子”為一個異常物件
class XiaoHeiZi (Exception):
    pass

# 定義一個接受文字的函式,如果接收到的文字是“jijiao”,則用關鍵字raise去拉起“小黑子”這個自定義異常
def iKUN(name):
    if  name == 'jijiao':
        raise XiaoHeiZi()


try:
    iKUN('jijiao')
except XiaoHeiZi:
    print('你讓我拿什麼荔枝!!!')

traceback

當Python程式出現異常的時候通常會有一大串紅色的報錯,例如在執行下面這串程式碼

def level_3():
    print ('進入 level_3')
    a = [0]
    b = a[1]
    print ('離開 level_3')

def level_2():
    print ('進入 level_2')
    level_3()
    print ('離開 level_2')

def level_1():
    print ('進入 level_1')
    level_2()
    print ('離開 level_1')


level_1()

print('程式正常退出')

會得到如下報錯:

進入 level_1
進入 level_2
進入 level_3
Traceback (most recent call last):
  File "C:\Users\chx\AppData\Local\Programs\PyCharm Community\plugins\python-ce\helpers\pydev\pydevd.py", line 1534, in _exec
    pydev_imports.execfile(file, globals, locals)  # execute the script
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\chx\AppData\Local\Programs\PyCharm Community\plugins\python-ce\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "D:\programming\python\python_basic\error.py", line 47, in <module>
    level_1()
  File "D:\programming\python\python_basic\error.py", line 43, in level_1
    level_2()
  File "D:\programming\python\python_basic\error.py", line 38, in level_2
    level_3()
  File "D:\programming\python\python_basic\error.py", line 33, in level_3
    b = a[1]
        ~^^^
IndexError: list index out of range

這裡的報錯有兩個資訊,一個是錯誤發生的位置在level_3函式內33行的b = a[1]處,第二個資訊就是說明了這行引起異常的程式碼, 是怎樣被 一層層的呼叫進來的,也就是函式呼叫棧的資訊。

而在使用了try-except處理異常後想看到該異常的呼叫棧資訊,則需要用到traceback模組,使用方法如下:

import traceback

def level_3():
    print ('進入 level_3')
    a = [0]
    b = a[1]
    print ('離開 level_3')

def level_2():
    print ('進入 level_2')
    level_3()
    print ('離開 level_2')

def level_1():
    print ('進入 level_1')
    level_2()
    print ('離開 level_1')


try:
    level_1()
except :
    print(f'未知異常:{traceback.format_exc()}')

print('程式正常退出')

筆記原始碼摘自白月黑羽教程

相關文章