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!

限定位置參數 (Positional-only)

使用 / 來分隔。/ 左邊的參數只能使用位置參數傳遞,不能使用關鍵字參數。

def func(pos_only, /, standard, keyword_only):
    print(pos_only, standard, keyword_only)

# 正確呼叫
func(1, 2, keyword_only=3)
func(1, standard=2, keyword_only=3)

# 錯誤呼叫 (TypeError)
# func(pos_only=1, standard=2, keyword_only=3)

限定關鍵字參數 (Keyword-only)

使用 * 來分隔。* 右邊的參數只能使用關鍵字參數傳遞。

def func(standard, *, key_only):
    print(standard, key_only)

# 正確呼叫
func(1, key_only=2)

# 錯誤呼叫 (TypeError)
# func(1, 2)

預設參數值

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 complex_func(a, b, /, c, d, *args, e, f, **kwargs):
    """
    a, b: 只能是位置參數 (Positional-only)
    c, d: 可以是位置或關鍵字參數
    args: 收集多餘的位置參數
    e, f: 只能是關鍵字參數 (Keyword-only)
    kwargs: 收集多餘的關鍵字參數
    """
    print(f"a, b: {a}, {b}")
    print(f"c, d: {c}, {d}")
    print(f"args: {args}")
    print(f"e, f: {e}, {f}")
    print(f"kwargs: {kwargs}")

complex_func(1, 2, 3, d=4, e=5, f=6, extra=7)

輸出:

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)

型別提示 (Type Hints)

Python 是動態語言,但可以使用型別提示來增加程式碼的可讀性,並讓 IDE 提供更好的開發體驗。

def greet(name: str, age: int = 20) -> str:
    return f"Hello {name}, you are {age} years old."

# name 預期為 str,age 預期為 int,函數回傳值預期為 str
message = greet("Alice", 25)
型別提示不會在執行時強制檢查型別,它主要是給開發者和工具(如 mypy)參考用的。

變數作用域 (Scope)

變數的可見範圍稱為作用域。

區域變數 (Local)

在函數內部定義的變數,只能在該函數內部使用。

def func():
    x = 10  # 區域變數
    print(x)

func()
# print(x)  # 會報錯 NameError,外部無法存取

全域變數 (Global)

在函數外部定義的變數。如果在函數內要修改全域變數,需要使用 global 關鍵字。

count = 0  # 全域變數

def increment():
    global count
    count += 1

increment()
print(count)  # 1

函數是物件

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]