1. 什麼是 Python 的預設參數?【初學者也能輕鬆理解】
在使用 Python 的函式時,有時為每個參數都傳入值會顯得麻煩。這時候預設參數就派上用場了。透過設定預設參數,當呼叫函式時可以省略部分參數,讓程式碼更簡潔且彈性更高。本文將解說預設參數的基本概念與使用方式。
1.1 什麼是預設參數?
在 Python 的函式中,可以為參數設定預設值(初始值),這就稱為「預設參數」。當函式定義了預設參數後,在呼叫函式時若省略該參數,就會自動套用事先設定的預設值。
預設參數的基本語法
def 函式名稱(參數名稱=預設值):
處理內容
使用這種語法,可以讓函式的參數變成可選項目,進一步提升程式碼的可讀性與靈活性。
1.2 預設參數的基本用法
讓我們透過實際程式碼範例,來理解如何使用 Python 的預設參數。
基本範例
def greet(name="訪客"):
print(f"你好,{name}!")
greet() # 輸出:你好,訪客!
greet("佐藤") # 輸出:你好,佐藤!
上面的函式 greet()
為 name
參數設定了預設值 "訪客"
。當不傳入任何參數時,name
就會使用該預設值。而當像 greet("佐藤")
這樣傳入參數時,則會使用提供的值。
具有多個預設參數的函式
函式也可以同時設定多個預設參數。
def introduce(name="匿名", age=20):
print(f"我是{name},{age}歲。")
introduce() # 輸出:我是匿名,20歲。
introduce("田中") # 輸出:我是田中,20歲。
introduce("田中", 25) # 輸出:我是田中,25歲。
如上例所示,設定多個預設參數後,呼叫函式時就能更彈性地傳入必要參數。
使用預設參數的優點
使用預設參數有以下幾個好處:
- 讓程式碼更簡潔(可省略非必要的參數)
- 避免錯誤(避免因缺少參數而發生錯誤)
- 提升函式的通用性(透過預設值,可支援更多使用場景)
1.3 預設參數的應用場景
預設參數在各種場景中都非常實用,以下是常見的使用情境。
1. 設定選項
在函式中為選項設定預設值,可以讓使用者視需要調整參數。
def download_file(url, timeout=10):
print(f"正在下載 {url}(限時 {timeout} 秒)")
download_file("https://example.com") # 輸出:正在下載 https://example.com(限時 10 秒)
download_file("https://example.com", 5) # 輸出:正在下載 https://example.com(限時 5 秒)
在此範例中,timeout
預設值為 10
,若呼叫時未指定,則自動使用該值。
2. 輸出日誌訊息
在函式中加入預設的日誌訊息級別,可以提升除錯時的可讀性。
def log_message(message, level="INFO"):
print(f"[{level}] {message}")
log_message("開始處理") # 輸出:[INFO] 開始處理
log_message("發生錯誤", "ERROR") # 輸出:[ERROR] 發生錯誤
本範例中,level
的預設值為 "INFO"
,當沒有指定時,會使用該級別。
1.4 小結
Python 的預設參數是一項讓函式設計更具彈性的便利功能。
- 設定預設參數後,可省略該參數來呼叫函式
- 可同時設定多個預設參數
- 讓程式碼更簡潔,提升可讀性與通用性
- 適用於選項設定、日誌輸出等多種情境
下一節將說明使用預設參數時需要注意的事項,以及常見的錯誤與解決方法!
2. Python 預設參數的基本用法
在前一章中,我們介紹了 Python 預設參數的基本概念。
本章將透過實際的程式碼範例,詳細說明如何善用預設參數。
2.1 定義帶有預設參數的函式
以下是定義含有預設參數的函式的範例寫法:
def 函式名稱(參數1=預設值1, 參數2=預設值2, ...):
處理內容
具體範例
def greet(name="訪客", message="你好"):
print(f"{name},{message}")
greet() # 輸出:訪客,你好
greet("佐藤") # 輸出:佐藤,你好
greet("佐藤", "你好嗎?") # 輸出:佐藤,你好嗎?
如上例所示,如果省略參數,將會使用預設值;若指定參數,則會使用提供的值。
2.2 結合預設參數與關鍵字參數
在呼叫函式時使用關鍵字參數(keyword arguments),可以更彈性地指定參數。
使用關鍵字參數的範例
def introduce(name="匿名", age=20, country="日本"):
print(f"我是{name},{age}歲,來自{country}。")
introduce() # 輸出:我是匿名,20歲,來自日本。
introduce(name="田中") # 輸出:我是田中,20歲,來自日本。
introduce(age=25, name="山本") # 輸出:我是山本,25歲,來自日本。
introduce(country="美國", age=30) # 輸出:我是匿名,30歲,來自美國。
➡ 使用關鍵字參數可以不按順序傳遞參數,進而提升程式碼的可讀性。
2.3 預設參數的應用時機
透過預設參數,可讓某些特定情境下的程式設計更簡潔。
① 記錄日誌
可設定預設的日誌等級,實現一致性的日誌輸出管理。
def log_message(message, level="INFO"):
print(f"[{level}] {message}")
log_message("啟動應用程式")
# 輸出:[INFO] 啟動應用程式
log_message("發生錯誤", "ERROR")
# 輸出:[ERROR] 發生錯誤
② API 請求的參數
在呼叫 API 時預設 timeout 值,可降低錯誤風險。
import requests
def fetch_data(url, timeout=10):
response = requests.get(url, timeout=timeout)
return response.json()
# 使用預設的 10 秒 timeout
data = fetch_data("https://api.example.com/data")
# 自訂 timeout 時間
data = fetch_data("https://api.example.com/data", timeout=5)
③ 簡化計算邏輯
透過預設參數,可以讓計算過程更具彈性。
def calculate_price(price, tax_rate=0.10):
return price * (1 + tax_rate)
print(calculate_price(1000)) # 輸出:1100.0(稅率10%)
print(calculate_price(1000, 0.08)) # 輸出:1080.0(稅率8%)
2.4 小結
- 設定預設參數可以提升函式的使用便利性
- 搭配關鍵字參數使用時,不需在意參數順序
- 預設參數廣泛應用於日誌輸出、API 請求、計算處理等場景

3. 使用預設參數時的注意事項【常見錯誤與對策】
Python 的預設參數雖然方便,但若使用不當,可能導致預期外的錯誤或 Bug。
本章將介紹使用預設參數時應注意的地方,以及常見錯誤的原因與解決方法。
3.1 注意預設參數的順序!
在 Python 中,具有預設值的參數,必須寫在沒有預設值的參數後面。
如果順序錯誤,會導致SyntaxError(語法錯誤)。
❌ 錯誤範例(會出現錯誤)
def func(x=0, y): # 錯誤:預設參數不能寫在非預設參數前
print(x, y)
➡ 因為 x=0
在 y
前面,Python 會回報語法錯誤。
✅ 正確範例
def func(y, x=0): # OK
print(x, y)
➡ 將非預設參數(y
)寫在前面,即可避免錯誤。
3.2 不要將可變物件(list、dict)設為預設值
如果將list 或 dict 等可變物件當作預設參數,會造成意料之外的行為。
因為在 Python 中,預設值只在函式定義的當下評估一次,之後每次呼叫都會重複使用該物件。
❌ 錯誤範例(會產生 Bug)
def add_item(item, item_list=[]):
item_list.append(item)
return item_list
print(add_item("apple")) # 輸出:['apple']
print(add_item("banana")) # 輸出:['apple', 'banana'] ← 預期外的行為!
➡ 因為 item_list=[]
是共享的,每次呼叫函式時都會使用同一個 list。
✅ 正確範例
def add_item(item, item_list=None):
if item_list is None:
item_list = [] # 每次建立新的 list
item_list.append(item)
return item_list
print(add_item("apple")) # 輸出:['apple']
print(add_item("banana")) # 輸出:['banana'] ← 正常行為!
➡ 將預設值設為 None
,再於函式內部建立新物件,即可避免這種錯誤。
3.3 注意預設參數的評估時機!
在 Python 中,預設參數的值會在函式「定義」時就被計算,
如果設定了與時間相關的值為預設值,可能導致非預期的結果。
❌ 錯誤範例(會產生 Bug)
import datetime
def log_message(message, timestamp=datetime.datetime.now()):
print(f"[{timestamp}] {message}")
log_message("第一次記錄")
log_message("第二次記錄") # 時間不會變!
➡ 因為 datetime.datetime.now()
在函式定義時就被執行,之後所有呼叫都用同一個時間值。
✅ 正確範例
import datetime
def log_message(message, timestamp=None):
if timestamp is None:
timestamp = datetime.datetime.now()
print(f"[{timestamp}] {message}")
log_message("第一次記錄")
log_message("第二次記錄") # 每次都會有不同時間
➡ 用 None
當預設值,並在函式內部處理時間的取得。
3.4 注意位置參數與關鍵字參數的搭配
使用預設參數的函式時,要小心位置參數(positional)與關鍵字參數(keyword)混用時的順序與重複。
❌ 錯誤範例(會出錯)
def greet(name="訪客", message="你好"):
print(f"{name},{message}")
greet("你好", name="佐藤") # TypeError:位置與關鍵字參數重複
➡ "你好"
被當作 name
的位置參數,但又用 name="佐藤"
指定了相同參數,因此出錯。
✅ 正確範例
greet(name="佐藤", message="你好") # OK
greet("佐藤") # OK
➡ 適當區分位置與關鍵字參數,就能避免此類錯誤。
3.5 小結
- 具有預設值的參數必須寫在沒有預設值的參數之後
- 避免將 list、dict 等可變物件設為預設參數
- 預設值在函式定義時就會被評估,要避免使用時間依賴的值
- 正確使用位置參數與關鍵字參數,避免參數重複
4. 預設參數的評估時機與其影響
在 Python 中,預設參數的值是在函式被定義的當下就被評估一次,
此後每次呼叫函式時都會重複使用同一個物件。
如果不了解這項特性,可能會導致意料之外的 Bug。
本章將詳細說明預設參數的評估時機,並透過範例介紹正確的使用方式。
4.1 什麼是預設參數的評估時機?
一般而言,大家會以為 Python 中的變數在每次呼叫函式時都會重新指定值,但預設參數卻不是這樣,它們會在函式被定義時就一次性地被評估。
具體範例:預設值的評估時機
import datetime
def get_current_time(timestamp=datetime.datetime.now()):
print(f"目前時間:{timestamp}")
get_current_time() # 輸出範例:目前時間:2025-03-20 12:00:00
get_current_time() # 輸出相同時間:目前時間:2025-03-20 12:00:00(不會更新!)
➡ 每次呼叫都出現相同的時間,是因為 datetime.datetime.now()
是在函式定義時被執行了一次,
之後的呼叫都重複使用該值。
4.2 預設值評估時機可能造成的問題
這項特性可能導致以下常見 Bug。
問題1:預設值為可變物件(如 list 或 dict)時會共用資料
def append_to_list(value, my_list=[]):
my_list.append(value)
return my_list
print(append_to_list(1)) # 輸出:[1]
print(append_to_list(2)) # 輸出:[1, 2] ← 出現意外結果!
print(append_to_list(3)) # 輸出:[1, 2, 3]
➡ 因為所有呼叫共用同一個 list,資料會累積,不是每次都重新建立。
問題2:使用 dict 為預設值也會發生類似錯誤
def add_to_dict(key, value, my_dict={}):
my_dict[key] = value
return my_dict
print(add_to_dict("a", 1)) # 輸出:{'a': 1}
print(add_to_dict("b", 2)) # 輸出:{'a': 1, 'b': 2} ← 資料未重置!
➡ dict 也被重複使用,導致每次呼叫時前一次的資料還在。
4.3 如何避免因預設值評估造成的 Bug?
為了避免這類問題,最佳做法是將預設值設為 None
,並在函式內部手動建立新的物件。
✅ 正確寫法(解法)
def append_to_list(value, my_list=None):
if my_list is None:
my_list = [] # 每次都建立新的 list
my_list.append(value)
return my_list
print(append_to_list(1)) # 輸出:[1]
print(append_to_list(2)) # 輸出:[2] ← 如預期
print(append_to_list(3)) # 輸出:[3]
➡ 透過 None
判斷,確保每次都產生新的 list,避免資料共享的問題。
4.4 為什麼 None
是最佳選擇?
Python 中的 None
是不可變的(immutable),所以使用它作為預設值具有以下優點:
- 避免資料共享造成的錯誤
- 透過明確的
if
判斷邏輯,提升可讀性 - 可以根據需求在函式內動態建立適當的物件
使用 dict 時的正確寫法
def add_to_dict(key, value, my_dict=None):
if my_dict is None:
my_dict = {} # 每次建立新的 dict
my_dict[key] = value
return my_dict
print(add_to_dict("a", 1)) # 輸出:{'a': 1}
print(add_to_dict("b", 2)) # 輸出:{'b': 2} ← 正常行為
➡ 每次呼叫都會建立新的 dict,確保資料不會重複。
4.5 小結
- Python 的預設參數在函式定義時只會被評估一次,之後重複使用
- 使用 list、dict 等可變物件當預設值會導致資料共用,產生 Bug
- 正確做法是將預設值設為
None
,並在函式內部建立新物件 - 理解這個特性有助於避免錯誤,撰寫更安全的程式碼
5. Python 預設參數的實用應用技巧
在前面章節中,我們已經說明了 Python 預設參數的基本用法與注意事項。
本章將介紹實際開發中能派上用場的預設參數應用範例。
善用預設參數可以有效提升程式碼的可讀性與維護性。
5.1 使用預設參數來設計更方便的函式
預設參數的主要目的是提升函式的使用彈性與便利性。
以下是幾個常見情境,展示如何在設計函式時有效使用預設參數。
① 帶有設定選項的函式
如果函式中包含設定選項,預設參數可以讓使用者在大多數情況下不需手動指定每個參數。
def connect_to_database(host="localhost", port=3306, user="root", password=""):
print(f"正在連接資料庫:{host}:{port}, 使用者:{user}")
connect_to_database()
# 輸出:正在連接資料庫:localhost:3306, 使用者:root
connect_to_database(host="db.example.com", user="admin")
# 輸出:正在連接資料庫:db.example.com:3306, 使用者:admin
➡ 透過預設值提供標準設定,使用者僅需修改必要部分。
5.2 哪些情況適合/不適合使用預設參數?
✅ 適合使用預設參數的情況
- 函式的某些參數是可選的
- 範例:設定值(如
port=3306
、timeout=10
)
- 想提供常用的預設行為
- 範例:日誌等級(如
level="INFO"
)
- 希望讓函式更簡潔,具備標準化行為
- 範例:預設使用者名稱(如
name="訪客"
)
❌ 不建議使用預設參數的情況
- 預設值是可變物件(如 list 或 dict)
- ➡ 使用
None
並於函式內初始化
- 每次呼叫時都需要不同值的場景
- 範例:取得目前時間(如
timestamp=datetime.datetime.now()
)時,應以None
控制延遲評估
- 參數的順序具有邏輯性或會影響可讀性
- ➡ 務必將預設參數放在最後
5.3 小結
- 妥善使用預設參數有助於提升程式的可讀性與彈性
- 可應用於資料庫連線、API 請求、日誌記錄、使用者設定等場景
- 避免使用可變物件為預設值,注意參數的順序
- 善用預設參數設計更實用、更具彈性的 Python 函式!
6. 有關 Python 預設參數的常見問題(FAQ)
我們已經詳細介紹了 Python 預設參數的各種用法與注意事項,
但實際使用時仍會有許多疑問。
本章整理了開發者常見的預設參數相關問題與解答。
6.1 關於預設參數基本概念的常見問題
Q1. 函式參數的順序有什麼限制嗎?
A: 有的。帶有預設值的參數必須寫在沒有預設值的參數之後。
否則會出現 SyntaxError
(語法錯誤)。
❌ 錯誤範例(會出錯)
def func(x=10, y): # 錯誤:預設參數不能放在非預設參數之前
print(x, y)
✅ 正確範例
def func(y, x=10): # OK
print(x, y)
➡ 遵循「非預設參數在前、預設參數在後」的順序即可。
6.2 關於可變物件(list、dict)的常見問題
Q3. 為什麼使用 list 或 dict 作為預設參數會導致 Bug?
A: 在 Python 中,預設參數的值是在函式定義時就被計算一次,之後所有呼叫都會共用該物件。
如果預設值是 list 或 dict(這些是可變物件),那麼會造成資料在不同呼叫之間被共用,產生意外的行為。
❌ 錯誤範例
def add_item(item, item_list=[]): # 不建議的寫法
item_list.append(item)
return item_list
print(add_item("apple")) # 輸出:['apple']
print(add_item("banana")) # 輸出:['apple', 'banana'] ← 資料被保留了!
✅ 正確寫法(使用 None
)
def add_item(item, item_list=None):
if item_list is None:
item_list = [] # 每次產生新的 list
item_list.append(item)
return item_list
print(add_item("apple")) # 輸出:['apple']
print(add_item("banana")) # 輸出:['banana'] ← 正確的行為
➡ 利用 None
來延遲初始化,可有效避免共享資料的問題。
6.3 其他與預設參數有關的問題
Q5. 預設參數的值是在什麼時候被評估?
A: 預設參數的值會在函式「被定義」時就被評估一次。
所以如果你希望每次呼叫都取得不同的值(例如目前時間),那麼就不能將該表達式寫在預設值中。
❌ 錯誤範例
import datetime
def log_message(message, timestamp=datetime.datetime.now()):
print(f"[{timestamp}] {message}")
log_message("第一次")
log_message("第二次") # 兩次輸出相同的時間!
✅ 正確寫法
def log_message(message, timestamp=None):
if timestamp is None:
timestamp = datetime.datetime.now() # 每次呼叫都重新計算
print(f"[{timestamp}] {message}")
log_message("第一次")
log_message("第二次") # 這次會顯示不同的時間
➡ 記得用 None
做預設值,並在函式內處理動態資料。
6.4 小結
- 預設參數必須放在非預設參數的後面
- 可以使用關鍵字參數來不依照順序指定參數
- list 或 dict 等可變物件不應直接作為預設參數(請使用
None
來初始化) - 預設參數的值在定義時就被評估,動態資料應使用延遲處理
- 也可以將函式作為預設參數,實現動態行為
7. 總結與下一步建議
本篇文章詳細介紹了 Python 預設參數的用法。
妥善使用預設參數可以提升程式碼的可讀性與彈性,並有效預防常見錯誤。
接下來你可以這麼做:
- 實際撰寫使用預設參數的函式,觀察其執行行為
- 練習使用
None
做為預設值,並在函式內動態處理 - 試著結合預設參數與關鍵字參數,設計更彈性的函式
掌握 Python 預設參數的運用技巧,寫出更簡潔、更安全、更強大的程式碼吧! 🚀