函式
給一段程式取個名字,之後就叫得動它。 · ⏱ 約 30 分鐘
你會學到三件事
def 定義一個函式
- 參數進去、回傳值出來
- 函式裡面的變數只活在裡面
開始之前
第 2 課你給一個值取了名字。這一課要給一段程式取名字。
而你其實一直在用別人寫好的:print、len、input、int 都是函式。
一、def
def add(a, b):
return a + b
print(add(3, 4)) # 7
def add(a, b):
↑ ↑ ↑ ↑
關鍵字 名字 參數 冒號(和 if / for 一樣)
return a + b
└─ 縮排 = 函式的身體
⚠️ 函式要先定義才能用——定義寫在呼叫的後面會 NameError。
二、return
return 同時做兩件事:
- 把值交出去
- 立刻結束這個函式——後面的行不會跑
def f(n):
return n
print("印不出來") # ← 永遠不會跑
沒有 return 的函式回傳 None:
def greet(name):
print("你好," + name)
x = greet("小明")
print(x) # None
⚠️ 這是一個常見的困惑:「印出來」和「交出去」是兩件不同的事。
|
給誰 |
print(x) |
給人看 |
return x |
給呼叫它的那段程式用 |
三、參數可以有預設值
def greet(name, greeting="你好"):
print(greeting + "," + name)
greet("小明") # 你好,小明
greet("小明", "早安") # 早安,小明
⚠️ 有預設值的參數要放後面。 def f(a=1, b) 是語法錯誤。
四、🔴 裡面的變數只活在裡面
def f():
x = 10
print(x)
f()
print(x) # 💥 NameError:外面沒有 x
函式裡宣告的變數叫區域變數——函式結束它就消失了。
好處是:你在函式裡取什麼名字,都不會撞到外面的東西。
⚠️ 反過來,函式讀得到外面的變數,而改不到:
total = 0
def add():
total = total + 1 # 💥 UnboundLocalError
要改外面的東西,正確的做法是回傳它:
def add(total):
return total + 1
total = add(total)
(有個 global 關鍵字可以強行改,而幾乎永遠不該用它。)
五、為什麼要寫函式
① 同一段程式要用好幾次 → 不用複製貼上
② 一段程式做的事需要一個名字 → 讀的人不必看細節
③ 可以單獨測試那一小段 → 出錯時範圍小
函式不是「進階語法」——它是你第一次覺得
「這幾行我不想再寫一遍」的時候,自然會想要的東西。
完成的樣子
def add(a, b):
return a + b
def greet(name):
print("你好," + name)
print(add(3, 4))
greet("小明")
換你了
寫一個 is_leap(year),回傳 True 或 False(第 5 課那個閏年規則)。
⚠️ 要 return,不要 print——這樣它才用得進 if is_leap(2000):。
這一課你做了什麼
- 你用
def 定義了兩個函式
- 你分得出
print(給人看)和 return(交出去)
- 你知道函式裡的變數只活在裡面
如果卡住了
| 你看到 |
多半是因為 |
NameError: add |
函式定義寫在呼叫的後面了 |
函式回傳 None |
少了 return |
UnboundLocalError |
在函式裡改了外面的變數。改成回傳它 |
TypeError: missing argument |
呼叫時參數個數不對 |
| 函式印出來了卻不能拿來用 |
print 不是 return |
在編輯器打開這一課 →