函式與例外
定義函式,以及讓錯誤變成一條可以走的路。 · ⏱ 約 35 分鐘
你會學到三件事
def:不用寫回傳型別,而可以有預設值
lambda 和 *args
try / except:錯誤不是當機,是一條分支
開始之前
C++ 的函式要寫回傳型別和每個參數的型別。
Python 兩個都不用,而換來的是你要自己知道。
🟢 先把編輯器打開,跟著下面一起做:跟著做
一、def
參數可以有預設值:
1def add(a, b=1):2 return a + b3 4print(add(3)) # 4 ← b 用預設值5print(add(3, 4)) # 7
b=1 是預設值:呼叫時不給就用它。
⚠️ 有預設值的參數要放在後面。 def f(a=1, b) 是語法錯誤。
⚠️ 預設值不要用 list(def f(items=[]))。那個 list 是所有呼叫共用同一個,
而不是每次新的。這是 Python 最有名的一個坑,先知道有這件事就好。
二、*args:數量不定
前面加一個星號,它就收得下任意多個:
1def total(*args):2 return sum(args)3 4print(total(1, 2, 3)) # 6
*args 把「傳進來的所有東西」收成一個 tuple。
積木盤上 sum 那一顆寫著「… 的總和」。
sum() 是內建的。Python 有很多這種內建函式(len max min sorted sum),
遇到「我想做某件很常見的事」時,先查一下有沒有。
三、lambda:一次性的小函式
只用一次的小函式可以不取名字:
1double = lambda x: x * 22print(double(5)) # 10
它就是一個沒有名字的 def,而只能寫一個運算式。
積木盤上它寫著「臨時函式」——名字就是它的用途。
它的用處在「把一個函式當參數傳進去」:
🔎 這一段是試一下——打了看結果就好,不要留在程式裡。
1sorted(names, key=lambda s: len(s)) # 依長度排序
⚠️ 不要用 lambda 取代 def。 上面那個 double = lambda x: ...
其實應該寫成 def double(x): return x * 2,一樣長,而好讀又好除錯。
四、try / except
積木上 try 那一顆寫著「嘗試 …」,另外兩格是
「沒出錯才 …」與「最後一定 …」。
接住的時候要說接住哪一種:
1try:2 n = int("abc")3except ValueError:4 print("轉換失敗")
int("abc") 轉不出來,於是它丟出一個 ValueError。
沒有 try 的話程式當場停掉;有的話,except 那一段接住它,程式繼續走。
|
意思 |
try: |
這一段可能會出事 |
except ValueError: |
出的是這種事的話,做這個 |
else: |
都沒出事的話(少用) |
finally: |
不管有沒有出事都要做(關檔案之類) |
⚠️ 不要寫光禿禿的 except:。 那會連你按 Ctrl+C 都接住,
而且會把你自己的打字錯誤一起吞掉。一個接住所有錯誤的程式,
與一個沒有錯誤的程式看起來一樣。
例外不是「錯誤處理」,是「另一條路」。
檔案不存在、使用者打錯字、網路斷了——這些本來就會發生,
它們不是 bug,是你的程式該想過的情況。
完成的樣子
這一課的參考做法——程式碼每一行的號碼,就印在對應的那塊積木上。
1def add(a, b=1):2 return a + b3 4def total(*args):5 return sum(args)6 7print(add(3))8print(add(3, 4))9print(total(1, 2, 3))10 11double = lambda x: x * 212print(double(5))13 14try:15 n = int("abc")16except ValueError:17 print("轉換失敗")
換你了
寫一個函式,讀進使用者輸入並轉成整數。打錯字的話要求他重打,而不是當掉。
提示:while True: + try + 成功就 return。
到編輯器做這一題:練習:打錯就要求重打,而不是當掉
做一個
寫一個 safe_div(a, b):b 有預設值 1,而除以 0 的時候回傳「不能除以零」。
用 safe_div(10, 4)、safe_div(10)、safe_div(10, 0) 各叫一次,把結果印出來。
🔴 safe_div(10) 印出來是 10.0 不是 10,想一下為什麼。
到編輯器做這一題:做一個:不會當掉的除法
這一課你做了什麼
- 你定義了帶預設值和不定數量參數的函式
- 你寫了一個
lambda,並知道大部分時候該用 def
- 你用
try / except 把一個錯誤變成一條分支
如果卡住了
| 你看到 |
多半是因為 |
SyntaxError: non-default argument follows default |
有預設值的參數要放後面 |
| 例外沒被接住 |
except 的型別不對。先寫 except Exception as e: print(e) 看看是什麼 |
函式回傳 None |
少了 return。Python 不寫 return 就回 None |
| 預設值 list 每次呼叫都變長 |
那個經典的坑。預設寫 None,進函式再建新的 |
在編輯器打開這一課 →