前幾天我們已經學會了如何存資料、做運算,以及用條件判斷與迴圈來控制流程。不過,如果程式越寫越大,一直重複貼相似的程式碼,不僅難以維護,也容易出錯。這時候,就需要用到 函式(Function)。
函式的角色就像是一個「工具」或「機器」:
在日常生活中:
今天會學到:
return
—— 如何讓函式把結果交回來。*args
、**kwargs
。return
,或使用錯誤的預設值。學會函式之後,程式就能更有架構,並且開始具備「模組化思維」,這也是邁向大型專案開發的重要基礎。
# 定義一個函式(Function):加總兩數
def add(a, b): # a, b 是[參數]
result = a + b
return result # 傳出[回傳值]
# 呼叫函式,給予[引數]
print(add(3, 5)) # 輸出:8
重點記憶:
def
定義函式,return
把資料傳出
名稱 | 定義位置 | 舉例 |
---|---|---|
參數 | 函式「定義」時 | def add(a, b) |
引數 | 函式「呼叫」時 | add(3, 5) |
return
def square(x): # x 是[參數]
return x * x # 傳出[回傳值]
y = square(4) # y 得到 16
print(y) # 輸出:16
❗ 如果沒寫
return
,會默認回傳None
*args
、**kwargs
)def greet(name="小明"):
print(f"哈囉,{name}!")
greet("阿華") # 傳入引數
greet() # 使用預設值
-- 若有印引數,則程式會採用引數阿華,若無,則使用預設的小明
*args
def total(*args): # args 會收集所有位置引數成為 tuple
return sum(args)
print(total(1, 2, 3)) # 輸出:6
print(total(1, 2, 3, 4, 5)) # 輸出:15
**kwargs
def profile(**kwargs): # kwargs 會收集所有關鍵字引數成為 dict
for k, v in kwargs.items():
print(f"{k}:{v}")
profile(name="小美", age=18)
# 輸出:
# name:小美
# age:18
return
def bad_add(a, b):
result = a + b
# 忘記寫 return
print(bad_add(3,5)) # 輸出 None,如圖1
def good_add(a, b):
result = a + b
return result # 正確回傳結果
print(good_add(3, 5)) # 輸出 8,如圖2
-- 圖1:--
圖2:
錯誤寫法:
def bad_append(item, target=[]): # 所有呼叫都用同一個 list
target.append(item)
return target
print(bad_append(1)) # [1]
print(bad_append(2)) # [1, 2] ← 上次的結果還在!
正確寫法:
def good_append(item, target=None):
if target is None:
target = [] # 每次都建立新的 list
target.append(item)
return target
print(good_append(1)) # [1]
print(good_append(2)) # [2] ← 正確!
def calculate(a, b):
return a + b, a - b, a * b # 回傳 tuple
# 接收多個回傳值
add_result, sub_result, mul_result = calculate(10, 3)
print(f"加:{add_result}, 減:{sub_result}, 乘:{mul_result}")
語法 | 意義 |
---|---|
def 函式名(參數): |
定義函式 |
return 值 |
傳出資料 |
函式名(引數) |
呼叫函式 |
參數 = 預設值 |
預設參數值 |
*args |
接收多個位置引數(tuple) |
**kwargs |
接收多個關鍵字引數(dict) |
def add(x, y):
"""加法運算"""
return x + y
def subtract(x, y):
"""減法運算"""
return x - y
def multiply(x, y):
"""乘法運算"""
return x * y
def divide(x, y=1):
"""除法運算,預設除以 1"""
if y == 0:
return "除以零錯誤"
return x / y
def show_all(x, y):
"""展示所有運算結果"""
print(f"加法:{add(x, y)}")
print(f"減法:{subtract(x, y)}")
print(f"乘法:{multiply(x, y)}")
print(f"除法:{divide(x, y)}")
# 測試
show_all(10, 5)
x = 100 # 全域變數
def test_scope():
x = 50 # 區域變數,只在函式內有效
print(f"函式內的 x:{x}")
test_scope() # 輸出:函式內的 x:50
print(f"函式外的 x:{x}") # 輸出:函式外的 x:100
# 一般函式
def square(x):
return x ** 2
# Lambda 函式(匿名函式)
square_lambda = lambda x: x ** 2
print(square(5)) # 25
print(square_lambda(5)) # 25
# 常用於排序、過濾
numbers = [3, 1, 4, 1, 5]
sorted_nums = sorted(numbers, key=lambda x: -x) # 降序排列
print(sorted_nums) # [5, 4, 3, 1, 1]
greet(name)
:輸出 你好,{name}!
even_or_odd(n)
:判斷奇偶,回傳 "偶數" 或 "奇數"calc(*nums)
:可接受任意數量數字,回傳 (總和, 平均)
# 題目 1
def greet(name):
"""打招呼函式"""
print(f"你好,{name}!")
# 測試
greet("Jr") # 輸出:你好,Jr!
# 題目 2
def even_or_odd(n):
if n % 2 == 0:
return "偶數"
else:
return "奇數"
# 測試
print(even_or_odd(4)) # 輸出:偶數
print(even_or_odd(7)) # 輸出:奇數
# 題目 3
def calc(*nums):
"""計算總和與平均
參數:
*nums: 任意數量的數字
回傳:
tuple: (總和, 平均)
"""
if not nums: # 如果沒有傳入數字
return 0, 0
total = sum(nums)
average = total / len(nums)
return total, average
# 測試
print(calc(1, 2, 3, 4, 5)) # 輸出:(15, 3.0)
print(calc(10, 20)) # 輸出:(30, 15.0)
def safe_divide(x, y):
"""安全的除法運算
參數:
x (float): 被除數
y (float): 除數
回傳:
float 或 str: 運算結果或錯誤訊息
"""
try:
if y == 0:
raise ZeroDivisionError("不能除以零")
return x / y
except ZeroDivisionError as e:
return f"錯誤:{e}"
except Exception as e:
return f"未知錯誤:{e}"
# 測試
print(safe_divide(10, 2)) # 5.0
print(safe_divide(10, 0)) # 錯誤:不能除以零