Python 函數 (Function)

函數是一段可重複使用的程式碼,用來執行特定的任務。函數讓程式碼更有組織、更容易維護和重複使用。

定義函數

使用 def 關鍵字定義函數:

def 函數名稱(參數):
    # 函數內容
    return 回傳值
def greet(name):
    return f"Hello, {name}!"

message = greet("Alice")
print(message)  # Hello, Alice!

呼叫函數

定義函數後,使用函數名稱加上括號來呼叫:

def say_hello():
    print("Hello!")

say_hello()  # 呼叫函數,輸出: Hello!
say_hello()  # 可以重複呼叫

參數 (Parameters)

位置參數

參數按照位置順序傳入:

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

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

關鍵字參數

呼叫時指定參數名稱,順序可以不同:

def greet(name, greeting):
    return f"{greeting}, {name}!"

# 位置參數
print(greet("Alice", "Hello"))  # Hello, Alice!

# 關鍵字參數
print(greet(greeting="Hi", name="Bob"))  # Hi, Bob!

# 混合使用(位置參數必須在前)
print(greet("Charlie", greeting="Hey"))  # Hey, Charlie!

預設參數值

def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Alice"))            # Hello, Alice!
print(greet("Bob", "Hi"))        # Hi, Bob!
print(greet("Charlie", "Hey"))   # Hey, Charlie!

預設參數不要使用可變物件(如 list、dict):

# 錯誤做法
def add_item(item, items=[]):
    items.append(item)
    return items

print(add_item(1)) # [1] print(add_item(2)) # [1, 2] - 意外!

正確做法

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

*args - 可變數量位置參數

def add(*numbers):
    return sum(numbers)

print(add(1, 2))        # 3
print(add(1, 2, 3, 4))  # 10
print(add())            # 0

*numbers 會將所有位置參數收集成一個 tuple:

def print_all(*args):
    print(type(args))  # <class 'tuple'>
    for arg in args:
        print(arg)

print_all("a", "b", "c")

**kwargs - 可變數量關鍵字參數

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=25, city="Taipei")

輸出:

name: Alice
age: 25
city: Taipei

**kwargs 會將所有關鍵字參數收集成一個 dict。

組合使用

參數順序:一般參數 → *args → 關鍵字參數 → **kwargs

def func(a, b, *args, option=True, **kwargs):
    print(f"a: {a}")
    print(f"b: {b}")
    print(f"args: {args}")
    print(f"option: {option}")
    print(f"kwargs: {kwargs}")

func(1, 2, 3, 4, 5, option=False, x=10, y=20)

輸出:

a: 1
b: 2
args: (3, 4, 5)
option: False
kwargs: {'x': 10, 'y': 20}

回傳值

使用 return 回傳值:

def square(x):
    return x ** 2

result = square(5)
print(result)  # 25

回傳多個值

其實是回傳一個 tuple:

def get_min_max(numbers):
    return min(numbers), max(numbers)

result = get_min_max([3, 1, 4, 1, 5, 9])
print(result)  # (1, 9)

# 解包
min_val, max_val = get_min_max([3, 1, 4, 1, 5, 9])
print(min_val, max_val)  # 1 9

沒有 return

沒有 returnreturn 後面沒有值,函數回傳 None

def greet(name):
    print(f"Hello, {name}!")

result = greet("Alice")  # 印出: Hello, Alice!
print(result)            # None

Docstring 文件字串

在函數開頭用三引號寫文件說明:

def calculate_area(radius):
    """
    計算圓的面積
    
    Args:
        radius: 圓的半徑
    
    Returns:
        圓的面積
    """
    import math
    return math.pi * radius ** 2

# 查看文件
print(calculate_area.__doc__)
help(calculate_area)

函數是物件

Python 中函數是一級物件 (first-class object),可以:

指定給變數

def greet(name):
    return f"Hello, {name}!"

say_hi = greet  # 將函數指定給變數
print(say_hi("Alice"))  # Hello, Alice!

作為參數傳遞

def apply_twice(func, value):
    return func(func(value))

def double(x):
    return x * 2

result = apply_twice(double, 3)
print(result)  # 12 (3 * 2 * 2)

作為回傳值

def create_multiplier(n):
    def multiplier(x):
        return x * n
    return multiplier

double = create_multiplier(2)
triple = create_multiplier(3)

print(double(5))  # 10
print(triple(5))  # 15

實際範例

計算 BMI

def calculate_bmi(weight, height):
    """
    計算 BMI
    
    Args:
        weight: 體重 (公斤)
        height: 身高 (公分)
    
    Returns:
        BMI 值和評語
    """
    height_m = height / 100
    bmi = weight / (height_m ** 2)
    
    if bmi < 18.5:
        status = "過輕"
    elif bmi < 24:
        status = "正常"
    elif bmi < 27:
        status = "過重"
    else:
        status = "肥胖"
    
    return round(bmi, 1), status

bmi, status = calculate_bmi(70, 175)
print(f"BMI: {bmi}, 狀態: {status}")

處理列表

def filter_by_condition(items, condition):
    """根據條件過濾列表"""
    return [item for item in items if condition(item)]

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

evens = filter_by_condition(numbers, lambda x: x % 2 == 0)
print(evens)  # [2, 4, 6, 8, 10]

greater_than_5 = filter_by_condition(numbers, lambda x: x > 5)
print(greater_than_5)  # [6, 7, 8, 9, 10]