首頁 > 軟體

Python學習之例外處理詳解

2022-03-14 13:01:33

本章節主要學習 python 中的例外處理,來看一下該章節的內容有哪些。首先我們需要了解 什麼是異常與異常的處理 ,然後再繼續 異常的語法結構

什麼是異常與例外處理

異常 —> 可以理解為不同尋常。

正常情況下,我們的程式是自上而下的逐行執行,執行到最後一行才會終止程式的執行。而異常的情況會導致我們的程式半途而廢停止了執行。一般情況下的停止執行都是因為我們的程式出錯而造成的,而異常就是錯誤,異常的出現會導致我們的程式崩潰並停止執行。這在我們的工作中是非常不友好的!

縱觀程式的一生,都不能保證說程式一定不會出錯。所以當遇到錯誤的時候,為了不影響程式的執行,我們就需要對這些異常進行處理, Python 中的異常機制,可以監控並捕獲到異常。當程式出現錯誤的時候對異常進行臨時妥善的處理,就可以使得程式繼續正常的執行。

總結:

異常的本質就是錯誤

異常的出現會導致程式的崩潰且會停止執行

監控異常並捕獲,將造成異常的程式進行妥善的處理可以使得程式能夠繼續正常的執行

接下來我們就快快的看一下 究竟如何捕獲異常並進行例外處理的語法吧。

異常的語法

try:                   # 異常的關鍵字,嘗試的意思
    <程式碼塊1>               # 被 try 關鍵字檢查並保護的業務程式碼塊
    
except <異常的型別>:         # 發現異常後的處理關鍵字,會跟隨一個錯誤型別(異常型別),異常型別可以不填寫
    <程式碼塊2>               # try 的程式碼塊出現錯誤之後,就會執行 except 的程式碼塊
                       # 這裡一般都是當 try 程式碼塊出現錯誤之後的補救邏輯

來看一個簡單的範例:

1 / 0		# 我們都知道 0 不能被整除,所以產生了下面這樣的報錯

# >>> 執行結果如下
# >>> ZeroDivisionError: division by zero 

# >>> 我們管程式碼的報錯叫做 異常的丟擲 ,這個報錯資訊告訴了我們為什麼報錯,同時業務也會被停止。
# >>> 在程式中,我們是允許出錯的,但是需要對可能遇見的異常捕獲,
# >>> 進行合理的處理,讓程式遇到異常可以合理的執行

看一下針對上文範例的異常進行的捕獲

try:
    1 / 0
except:
    print('注意:0 不可以被 1 整除')
    print('ZeroDivisionError: division by zero 已捕獲,程式繼續執行')

# >>> 執行結果如下
# >>> 注意:0 不可以被 1 整除
# >>> ZeroDivisionError: division by zero 已捕獲,程式繼續執行

# >>> 雖然 try 程式碼塊丟擲了異常,但是我們通過 except 進行了合理的規避,使得我們的程式繼續向下執行

接下來我們再利用我們之前學到的知識點 upper() 函數做一個小案例:

定義一個 upper ,利用 upper() 函數 。將傳入的字串轉為大寫,如傳入引數非 字串 ,捕獲該異常並處理。

def upper(str_data):
    new_str = None

    try:
        new_str = str_data.upper()
    except:
        print('upper() 函數轉換字元大寫失敗!', '返回結果為:', new_str)
    return new_str


result = upper('test')
print('傳入引數返回值為:', result)

# >>> 執行結果如下:
# >>> 傳入引數返回值為: TEST


result = upper(1)
print(result)

# >>> 執行結果如下:
# >>> upper() 函數轉換字元大寫失敗! 返回結果為: None

捕獲通用異常

剛剛我們通過 try…except… 捕獲了異常並進行了合理的處理,但是我們並不知道錯誤的原因是什麼。所以我們必須獲取 異常的型別 ,首先我們來學習一下如何獲取通用異常型別, 通用異常型別 是我們無法確定是那種異常的情況下使用的一種捕獲方法。

用法如下:

try:
    <程式碼塊>
except Exception as e:        # 把通用異常的錯誤原因轉換成變數 e , as 為關鍵字
                            # 也可以理解為 將 Exception 通用異常型別 起一個別名 e
                            # e 變數名可以起任意名字,一般約定成俗都會使用 e 作為異常捕獲的變數名
                            # e 就是 error 的縮寫
    <異常程式碼塊>

通用異常捕獲範例如下:

def upper(str_data):
    new_str = None

    try:
        new_str = str_data.upper()
    except Exception as e:
        print('upper() 函數轉換字元大寫失敗!', '返回結果為:{}'.format(e))
    return new_str


result = upper(1)
print(result)


# >>> 執行結果如下:
# >>> upper() 函數轉換字元大寫失敗! 返回結果為:'int' object has no attribute 'upper'

捕獲具體異常

捕獲具體的異常就是我們可以確定在 try 的程式碼塊中會出現哪種具體的異常型別,並將其捕獲的方法。語法方面與通用異常一樣,在異常型別區域書寫 具體的異常型別 就可以了。

我們以上文的 ZeroDivisionError: division by zero 為例

try:
    1 / 0
except ZeroDivisionError as e:		# 書寫指定的異常型別:ZeroDivisionError
    								# ZeroDivisionError 是Python內建的具體異常:0不能被整除
    print(e)

# >>> 執行結果如下:
# >>> division by zero

小節:思考一個問題,工作中我們是使用 通用的異常 還是 具體的異常 呢?

從方便的角度來說,使用通用的異常會比較簡單。開發成本低,不需要關心具體的異常型別是什麼。其實 Exception 也不知知道具體的異常是哪一種型別,它需要去浩瀚的異常庫查詢,找到之後進行對應的丟擲,雖然沒有 具體指定異常 處理的那麼快,但是這個處理速度也是無感知的。

如果我們能知道 try 程式碼塊中 可能出現的具體異常型別,還是希望使用具體的異常型別。這樣可以精準的對應錯誤;

==需要注意的是:當我們的 try 程式碼塊中,沒有出現我們指定的 具體異常 型別,程式碼執行依然是會報錯的。==所以各有利弊,可以根據我們工作中業務的具體情況進行使用。

如何捕獲多個異常

在我們平時的開發工作中,很可能在同一個程式碼塊中出現多個異常型別。那麼我們該如何支援多個異常的捕獲呢?

其實異常的捕獲是非常靈活的,也支援多個異常捕獲的方式。

捕獲多個異常 - 方法1

try:
    result = 1 / 0
except ZeroDivisionError as e1:
    print(e1)
except Exception as e2:            # 可以使用多個 except 來捕獲多個異常
    print('this is a public except , bug is %s' % e2)
    
# >>> 需要注意的是,當 except 程式碼塊中有多個異常的時候,當捕獲到第一個異常後,不會在繼續往下捕獲。

需要注意的是,當 except 程式碼塊中有多個異常的時候,當捕獲到第一個異常後,不會在繼續往下捕獲。

捕獲多個異常 - 方法2

try:
    result = 1 / 0
except (ZeroDivisionError, Exception) as e:        # 在 except 後面的小括號內定義多個 異常型別 ,(小括號其實是元組)
                                                # 當 except 後面使用元組包裹多個 異常型別 時,捕獲到哪種異常型別就丟擲哪種
    print(e)

範例如下:

def test():

    try:
        print(name)     # 因為不存在 name 這個變數,所以會丟擲一個 NameError: name 'name' is not defined 異常
                        # 嘗試捕獲  NameError 異常
    except (ZeroDivisionError, NameError) as e:
        print(e)
        print(type(e))


test()

# >>> 執行結果如下:
# >>> name 'name' is not defined
# >>> <class 'NameError'>

比較常用的捕獲異常方法是第二種。

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


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