Python 函式 (def)

Python 函式(Python Function)

這篇 Python 函式教學將帶你認識 def:把一段程式碼包起來、取個名字,需要時呼叫即可。函式是「程式碼重複使用」的基礎,前面寫的成績管理程式如果用函式改寫,每個選項的邏輯都能獨立成一塊,更好讀也更好維護。

定義與呼叫函式

def greet(name):
    """跟指定的人打招呼"""      # docstring:函式說明
    print(f"你好,{name}!")

greet("小明")
greet("小華")

執行輸出:

你好,小明!
你好,小華!
組成說明
def定義函式的關鍵字
greet函式名稱,命名規則與變數相同(snake_case)
name參數:呼叫時傳入的資料
docstring函式第一行的字串,說明用途(選擇性但建議寫)
縮排區塊函式的內容

return 回傳值

return 把結果傳回給呼叫端,沒有 return 的函式回傳 None

def add(a, b):
    return a + b

result = add(3, 5)
print(result)

def no_return():
    pass

print(no_return())

執行輸出:

8
None

return 執行的當下函式立刻結束,常用來提早離開:

def divide(a, b):
    if b == 0:
        return "除數不能為 0"
    return a / b

print(divide(10, 2))
print(divide(10, 0))

執行輸出:

5.0
除數不能為 0

預設參數與關鍵字引數

參數可以設定預設值;呼叫時用「名字=值」可以不照順序傳:

def make_tea(tea="紅茶", sugar="半糖", ice="少冰"):
    return f"{tea}({sugar}、{ice})"

print(make_tea())                       # 全用預設值
print(make_tea("綠茶"))                 # 依序覆蓋
print(make_tea(ice="去冰", tea="烏龍")) # 關鍵字引數,順序自由

執行輸出:

紅茶(半糖、少冰)
綠茶(半糖、少冰)
烏龍(半糖、去冰)

一次回傳多個值

回傳多個值其實是回傳 Tuple,搭配解包非常好用:

def min_max(nums):
    return min(nums), max(nums)

low, high = min_max([3, 8, 1, 9, 5])
print(f"最小 {low},最大 {high}")

執行輸出:

最小 1,最大 9

經典陷阱:可變預設參數

預設值只在定義時建立一次,用 List 當預設值會跨呼叫共用:

def add_item(item, items=[]):    # 危險!
    items.append(item)
    return items

print(add_item("a"))
print(add_item("b"))    # 預期 ['b'],實際上...

執行輸出:

['a']
['a', 'b']

正確寫法是用 None 當預設值,函式內再建立新 List:

def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item("a"))
print(add_item("b"))

執行輸出:

['a']
['b']

常見錯誤

1. TypeError: greet() missing 1 required positional argument

呼叫時少傳了必要參數。要嘛補上引數,要嘛幫參數設預設值。

2. 拿 None 繼續運算

函式忘了寫 return,呼叫端拿到 None 再運算就報 TypeError: unsupported operand type(s) for +: 'NoneType'。檢查函式每條路徑都有回傳值。

3. 可變預設參數共用

如上節範例,List/dict 當預設值會跨呼叫累積。預設值用 None,函式內再初始化。

總結

def 定義、return 回傳(沒寫就是 None)、預設參數讓呼叫更簡潔、關鍵字引數讓順序自由、多值回傳本質是 Tuple;唯一要背起來的陷阱:預設值不要用 List 或 dict。下一篇介紹參數的進階寫法:*args 與 **kwargs。

延伸閱讀