跳到內容

函式

函式是把一段程式包起來、取個名字,之後要用就呼叫它,不必一直重寫。這一章看怎麼定義函式、傳資料進去、把結果拿回來。

def 定義函式:def 後面接名字和一對括號,底下縮排的就是函式的內容。定義好之後,寫「名字加括號」就能呼叫它:

def greet(name):
print("你好," + name)
greet("小明")

括號裡的 name參數,呼叫時給的 "小明" 會被塞進去。按「下一步」時注意,呼叫 greet 那一刻,右邊的呼叫堆疊會多出一層,跳進函式裡執行。

前面的 greet 只是印東西。更常見的是讓函式算出一個結果交回來,用的是 return

def add(a, b):
return a + b
result = add(3, 5)
print(result)

add(3, 5) 執行到 return a + b,就把 8 交回呼叫的地方,存進 result。函式一旦 return,就結束、跳回原來的位置。

return 也可以一次回傳好幾個值,用逗號隔開;接收時同樣用逗號一次拆開:

def divide(a, b):
return a // b, a % b
quotient, remainder = divide(17, 5)
print("商是", quotient)
print("餘數是", remainder)

return a // b, a % b 一口氣把商和餘數都交回來,quotient, remainder = divide(17, 5) 再一次接住兩個。

參數可以給預設值。呼叫時沒提供,就用預設的;有提供,就用你給的:

def greet(name, greeting="你好"):
print(greeting + "" + name)
greet("小明")
greet("小美", "早安")

greet("小明") 沒給 greeting,用預設的「你好」;greet("小美", "早安") 則把預設值蓋掉。

呼叫時給的值叫引數。可以照順序給(位置引數),也可以指名道姓給(關鍵字引數):

def describe(name, age):
print(name, "今年", age, "")
describe("小明", 18)
describe(age=20, name="小美")

describe("小明", 18) 靠位置對應,第一個給 name、第二個給 agedescribe(age=20, name="小美") 直接指名,這樣順序就無所謂了。

return 不一定要放在最後。一遇到就可以回傳、結束函式。這常拿來先處理特殊情況,把主要的邏輯留到後面,不用層層巢狀的 if

def check_age(age):
if age < 0:
return "年齡不能是負的"
if age < 18:
return "未成年"
return "成年"
print(check_age(-5))
print(check_age(15))
print(check_age(30))

年齡是負的就直接回傳、不再往下;否則再看是不是未成年;都不是,才走到最後的「成年」。

None 是一個特別的值,代表「還沒有值」。它常拿來當一個變數的起始狀態,之後再判斷「到底填了沒」。判斷一個值是不是 None,習慣上用 is None(而不是 == None):

def find_min(numbers):
smallest = None
for n in numbers:
if smallest is None or n < smallest:
smallest = n
return smallest
print(find_min([5, 2, 8, 1, 9]))

這裡要自己找出最小值,一開始還沒看過任何數字,所以 smallest 先設成 None。迴圈裡 if smallest is None or n < smallest 的意思是「如果還沒記過任何數,或這個數更小,就更新」。這樣第一圈一定會先記下第一個數,之後才逐一比較。

接收任意多個引數:*args**kwargs

Section titled “接收任意多個引數:*args 與 **kwargs”

有時你不知道會傳幾個引數進來。參數前面加一個 *,就會把所有位置引數收集成一個元組:

def total(*numbers):
result = 0
for n in numbers:
result = result + n
return result
print(total(1, 2, 3))
print(total(10, 20, 30, 40))

total(1, 2, 3)total(10, 20, 30, 40) 傳的個數不同,函式裡的 numbers 都能一次收下、用迴圈加總。

加兩個 ***)則是把關鍵字引數收集成一個字典:

def show_info(**info):
for key in info:
print(key, "", info[key])
show_info(name="小明", age=18)

函式可以呼叫自己,這叫遞迴。關鍵是要有個停下來的條件,否則會無止盡地叫下去。下面用遞迴算階乘(5 的階乘是 5×4×3×2×1):

def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
print(factorial(5))

一直按「下一步」,看右邊的呼叫堆疊怎麼一層一層疊上去:factorial(5) 要先算 factorial(4)factorial(4) 又要 factorial(3)……一路到 factorial(0) 回傳 1,才逐層乘回來,最後得到 120。這個「堆疊疊起來又收回去」的過程,用步進看最清楚。