首頁 > 軟體

Python學習之自定義異常詳解

2022-03-16 10:01:02

在上一章我們學習了 異常的三個關鍵字,分別是try、except 以及 finally。我們知道在 try 程式碼塊中如果遇到錯誤就會丟擲異常,交給 except 提前定義好的錯誤型別進行匹配並捕獲,如果成功捕獲到異常就會交給 except 的程式碼塊進行執行,最後的 finally 是無論如何都會執行的程式碼塊。

那麼在 try 語法塊中是誰丟擲的異常?優勢如何丟擲的呢?首先丟擲異常的是 Python 的直譯器,它在指令碼執行的時候發現了錯誤並將其丟擲,而如何丟擲的呢?捕獲的異常優勢如何定義的呢?

帶著這樣的疑問,我們就學習一下如何自己書寫一個異常型別,並主動丟擲異常。

當我們學會了自定義一個異常以及主動丟擲異常的時候,就可以主宰一個異常的發生。在之前我們學習的如 NameError 、TypeError … 這些都是 Python 內建給我們定義好的,我們只能老老實實的使用他們。通過今天的學習,我們就可以變被動為主動,因為在實際工作中有太多的場景是 內建的異常所觸及不到的,而這時候使用我們自己定義的異常型別就可以更好的打通業務。

自定義丟擲異常關鍵字 - raise

raise 關鍵字的功能:可以將資訊已報錯的形式丟擲

raise 關鍵字的用法:範例如下

# 用法:
raise 異常型別(message)

# 引數:
# message:為要輸出的錯誤資訊
# 這樣的當程式執行到 raise 關鍵字這一行的時候,python 直譯器就會根據 raise 的要求丟擲異常錯誤。

# 返回值:
# 因為 raise 關鍵字是丟擲一個異常,所以是沒有返回值的

演示小案例 - 1

raise ValueError('使用 raise 主動丟擲異常。')

# >>> 執行結果如下:
# >>> Traceback (most recent call last):
# >>>   File "D:PycharmProjectsXXXXXXXXXXXXXXX.py", line 87, in <module>
# >>>     raise ValueError('使用 raise 主動丟擲異常。')
# >>> ValueError: 使用 raise 主動丟擲異常。

# >>> 這裡我們使用的是 ValueError 異常型別,其實我們可以使用任意的異常型別。
# >>> 實在不知道使用什麼異常型別,使用 Exception 也是一個不錯的選擇

演示小案例 - 2

def test(num):
    if num == 100:
        raise ValueError('傳入的引數 'num' 不可以為100')
    return num


result = test(100)
print(result)

# >>> 執行結果如下:
# >>> Traceback (most recent call last):
# >>>   File "D:PycharmProjectsXXXXXXXXXXXXXXX.py", line 21, in <module>
# >>>     result = test(100)
# >>>   File "D:PycharmProjectsXXXXXXXXXXXXXXX.py", line 17, in test
# >>>     raise ValueError('傳入的引數 'num' 不可以為100')
# >>> ValueError: 傳入的引數 'num' 不可以為100

那麼主動丟擲的 raise 能不能被捕獲呢?我們試一下。

def test(num):
    if num == 100:
        raise ValueError('傳入的引數 'num' 不可以為100')
    return num


# result = test(100)


def test2(num):
    try:
        return test(num)
    except ValueError as e:
        return e


result = test2(100)
print(result)

# >>> 執行結果如下:
# >>> 傳入的引數 'num' 不可以為100

再思考一個問題,如果 raise 關鍵字後面不跟隨錯誤型別,僅僅是 字串提示資訊,能否進行丟擲錯誤呢?

def test3():
    raise '主動丟擲異常'


test3()

# >>> 執行結果如下:
# >>> Traceback (most recent call last):
# >>>   File "D:PycharmProjectsXXXXXXXXXXXXXXX.py", line 38, in <module>
# >>>     test3()
# >>>   File "D:PycharmProjectsXXXXXXXXXXXXXXX.py", line 36, in test3
# >>>    raise '主動丟擲異常'
# >>> TypeError: exceptions must derive from BaseException
# >>> TypeError: 異常必須得基於基礎異常類 (BaseException:基礎異常類 - 也就是 'Exception')


# >>> 這裡的確丟擲了一個異常,但是並不是我們 raise 關鍵字主動丟擲的異常
# >>> 而是 Python直譯器發現 raise 關鍵字的用法不正確丟擲的 TypeError 的 異常型別

由此得出結論: raise 關鍵字 後面必須要配合一個 異常型別 ,才可以正常使用。

自定義異常類

Exception 是一個通用異常型別,在我們不知道、不確定該使用什麼異常型別的時候,就可以通過 Exception 來捕獲 或者 結合 raise 關鍵字主動丟擲異常。

同時 Exception 是所有異常型別的基礎類別(父類別),所以如果我們想要自定義一個異常型別,就需要繼承 Exception 基礎類別 。

基礎類別繼承之後我們還需要 自定義一個錯誤的訊息;滿足這兩個條件之後,我們就可以去自定義一個異常類。

總結:

  • 自定義異常必須繼承基礎類別:Exception
  • 需要在建構函式中自定義錯誤的資訊

來看一個範例:

class NewError(Exception):
    def __init__(self, message):
        self.message = message


def test():
    raise NewError('這是一個自定義異常')


try:
    test()
except NewError as e:
    print(e)
    
# >>> 執行結果如下:
# >>> 這是一個自定義異常

接下來 我們自定義一個檢查 name 傳參的異常,然後進行校驗

class CheckNameError(Exception):

    def __init__(self, message):
        self.message = message


def check_name(name):
    if name == 'Neo':
        raise CheckNameError(''Neo'的名字不可以作為傳參引數')
    return name

try:
    check_name('Neo')
except CheckNameError as e:
    print(e)
    
# >>> 執行結果如下:
# >>> Neo'的名字不可以作為傳參引數    


# 嘗試一下如果不使用我們 try 捕獲我們的自定義異常試試


class CheckNameError(Exception):

    def __init__(self, message):
        self.message = message


def check_name(name):
    if name == 'Neo':
        raise CheckNameError(''Neo'的名字不可以作為傳參引數')
    return name

check_name('Neo')

# >>> 執行結果如下:
# >>> __main__.CheckNameError: 'Neo'的名字不可以作為傳參引數

總結

該章節我們主要學習如何自定義丟擲一個異常,以及如何自動定義一個異常型別。

在工作中,定義一個符合業務場景的異常型別,可以更適合我們的開發與錯誤顯示。

到此這篇關於Python學習之自定義異常詳解的文章就介紹到這了,更多相關Python自定義異常內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com