身為一名程式設計師,無論你使用哪種語言編寫程式碼,除錯都是一項至關重要的技能。本文將教你如何在 Python 中利用斷言語句,有效率地進行除錯工作。
在專案開發過程中,你可能會定義多個模組,包含函式、類別等。實作上若有疏失,可能會導致錯誤或出現非預期的結果。斷言語句正可以幫助你偵測並修正這類錯誤。
本教學將深入探討 `assert` 語句的語法,並透過程式碼範例,讓你了解其在實務上的應用。此外,我們也會說明何謂斷言錯誤,以及如何運用它來排除開發期間的程式碼錯誤。
讓我們開始吧!
如何在 Python 中使用 `assert` 語句
首先,我們將學習 `assert` 語句的語法,接著實際操作一些範例。
`assert` 語句的語法
在 Python 中,`assert` 語句的語法如下:
assert expression, message
其中:
expression
是一個有效的 Python 運算式,可以評估變數值的條件、變數的真偽、函式的回傳值等。- 如果
expression
的計算結果為True
,`assert` 語句不會拋出錯誤,也不會返回任何值,代表程式運作正常。 - 如果
expression
的計算結果為False
,將會觸發 `AssertionError` 異常。 message
是一個可選的字串,當 `AssertionError` 異常觸發時,它會在回溯訊息中顯示。
接下來,我們將透過幾個範例,說明 `assert` 語句如何幫助我們撰寫更清晰且無錯誤的程式碼。
你可以在這個 GitHub Gist 中找到本教學所使用的程式碼範例。
Python 的 `assert` 語句範例
假設你的程式碼中定義了一個折扣變數,你希望它的值永遠小於或等於 max_discount
。為了確保折扣變數不會意外地被設定成不合理的值,你可以使用斷言來驗證 discount <= max_discount
這個條件是否成立。
>>> max_discount = 50
>>> discount = 20
>>> assert discount <= max_discount
在這個例子中,discount
(20) 小於 max_discount
(50),所以 `assert` 語句不會拋出任何錯誤。
斷言錯誤異常
如果折扣變數被設定成大於 max_discount
的值,就會觸發 `AssertionError` 異常。
>>> discount = 75
>>> assert discount <= max_discount
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
我們知道 `assert` 語句允許我們設定一個可選的訊息字串。
我們可以透過訊息字串,提供更詳盡的診斷資訊。以下程式碼中,我們在 `assert` 語句中加入了一個 Python f-string,其中包含了 discount
和 max_discount
的值。
>>> assert discount <= max_discount, f"discount should be at most {max_discount}; got discount = {discount}"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: discount should be at most 50; got discount = 75
如上所示,`AssertionError` 異常現在包含了 discount
和 max_discount
變數的值,讓開發者更容易判斷錯誤發生的原因。
使用 `assert` 偵錯和測試 Python 函式
在定義函式時,有時可能會不小心引入錯誤(邏輯錯誤),導致函式無法如預期般運作。
讓我們舉個例子。假設某堂課進行了一項測驗,學生可以選擇是否挑戰額外的加分題。只要學生挑戰了加分題,就可以在測驗中獲得額外 10 分的加分。 😄
考慮以下的 get_final_score
函式:
- 它接收目前的成績、加分和一個布林值。
- 如果學生挑戰了加分題 (布林值為
True
),他們將比目前的成績多獲得 10 分。 - 函式接著返回最終成績。
def get_final_score(score,bonus):
if bonus:
score += 10
return score
讓我們對這個函式進行幾次呼叫。當分數為 34 和 40,且 bonus
分別設定為 True
和 False
時,最終成績分別為 44 和 40。
print(get_final_score(34,True))
# 44
print(get_final_score(40,False))
# 40
然而,測驗的最高分是 50 分。因此,如果學生獲得 49 分,並且挑戰了加分題,函式 get_final_score
會很高興地計算出最終成績為 59。
print(get_final_score(49,True))
# 59
技術上來說,這是可行的。但是,假設學生分數不能超過測驗的最大可能分數。 🙂
因此,讓我們初始化一個 max_score
變數,並將函式返回的分數記錄在 final_score
變數中。
接著,我們添加一個斷言來檢查 final_score
是否小於等於 max_score
。
def get_final_score(score,bonus):
if bonus:
score += 10
return score
final_score = get_final_score(47,True)
max_score = 50
assert final_score <= max_score
現在,我們收到呼叫 get_final_score(47,True)
時所觸發的 `AssertionError` 異常:
Traceback (most recent call last):
File "main.py", line 17, in <module>
assert final_score <= max_score
AssertionError
現在,我們為 Python `assert` 語句添加一個描述性的 f-string:
assert final_score <= max_score,f"final_score should be at most {max_score}; got {final_score}"
Traceback (most recent call last):
File "main.py", line 17, in <module>
assert final_score <= max_score,f"final_score should be at most {max_score}; got {final_score}"
AssertionError: final_score should be at most 50; got 57
修改函式
讓我們回頭修改 get_final_score
函式的定義,以修正意外行為:
get_final_score
函式現在也接受max_score
作為參數。- 我們檢查
bonus
是否為True
。如果是True
,則將 10 分加到score
變數。 - 然後,我們檢查
score
是否大於max_score
。如果是,我們返回max_score
。 - 否則,我們返回
score
。
我們現在已經確保最終分數永遠小於或等於 max_score
。
def get_final_score(score,bonus,max_score):
if bonus:
score += 10
if score > max_score:
return max_score
return score
作為一個快速練習,請撰寫一些斷言,以確認函式現在是否如預期般運作。
關於 `AssertionError` 異常的注意事項
雖然當運算式計算結果為 False
時會發生 AssertionError
異常,但我們應該記住不要將此類錯誤作為例外處理。也就是說,我們不應該這樣做:
try:
<doing this>
except AssertionError:
<do this>
在前面關於 get_final_score
的範例中,我們使用斷言來檢查 final_score
是否小於 max_score
。然後,我們修改了函式定義,使得不再有斷言錯誤。
這正是斷言的用途所在。它們是程式碼的健全性檢查,有助於撰寫更清晰的程式碼。另一方面,例外處理是在執行期間預測和處理意外錯誤,通常包含無效的輸入類型和值。
總而言之,您應該使用 Python 的 `assert` 語句進行有效除錯,而不是將 `AssertionError` 當作例外處理。
結論
本教學幫助您了解如何在 Python 中使用 `assert` 語句。以下是您所學內容的總結:
- Python 斷言語句 (
assert
) 採用斷言運算式的形式,用於檢查運算式是否為真。如果其計算結果不是True
,則會引發AssertionError
異常。 - 您還可以使用語法
assert expression, message
的斷言。每當發生AssertionError
異常時,將會印出訊息字串。 - 您應該記住不要實施例外處理來處理斷言錯誤,並將斷言用作有用的除錯工具,以檢查程式碼的完整性。
身為開發人員,斷言可以協助您進行除錯。為了確保專案中的所有獨立元件(模組)如預期般運作,您可以學習如何使用 Python 撰寫單元測試。
接下來,你可以參考一些適合初學者的 Python 專案列表。