python的方法的參數除了可以使用標識符,還可以使用*和**作為參數,這些符號在Python中常用於處理可變數量的參數(也稱為“可變參數”或“星號參數”)。
注意:*通常與變量名結合使用,如*args(表示任意數量的位置參數);**通常如**kwargs(表示任意數量的關鍵字參數)。這些名字是慣例,不是必須的,可以用其他名字替換。
1. * 的用法(可變位置參數)
- 在函數定義中:
*用於收集任意數量的位置參數(positional arguments),這些參數會被打包成一個元組(tuple)。這允許函數接受不定數量的參數,而無需預先指定。
- 語法:
def func(固定參數, *args): ... *args收集所有多餘的位置參數。- 位置:
*args必須在固定位置參數之後,在**kwargs之前(如果有)。
- 在函數調用中:
*用於“展開”(unpack)一個可迭代對象(如列表、元組),將其元素作為位置參數傳入函數。
- 語法:
func(*iterable) - 這相當於將iterable的每個元素逐個作為位置參數傳遞。
示例(定義和調用結合)
# 函數定義中使用 *
def sum_numbers(*args):
total = 0
for num in args: # args是一個元組
total += num
return total
# 調用:直接傳入多個位置參數
print(sum_numbers(1, 2, 3)) # 輸出: 6 (args = (1, 2, 3))
# 函數調用中使用 * 展開
numbers = [4, 5, 6] # 列表
print(sum_numbers(*numbers)) # 輸出: 15 (相當於 sum_numbers(4, 5, 6))
2. ** 的用法(可變關鍵字參數)
- 在函數定義中:
**用於收集任意數量的關鍵字參數(keyword arguments),這些參數會被打包成一個字典(dict)。鍵是參數名,值是參數值。
- 語法:
def func(固定參數, **kwargs): ... **kwargs收集所有多餘的關鍵字參數。- 位置:
**kwargs必須在所有其他參數之後(包括*args)。
- 在函數調用中:
**用於“展開”一個字典,將其鍵值對作為關鍵字參數傳入函數。
- 語法:
func(**dictionary) - 這相當於將字典的每個鍵值對作為
key=value形式傳遞。
示例(定義和調用結合)
# 函數定義中使用 **
def print_info(**kwargs):
for key, value in kwargs.items(): # kwargs是一個字典
print(f"{key}: {value}")
# 調用:直接傳入多個關鍵字參數
print_info(name="Alice", age=30, city="New York")
# 輸出:
# name: Alice
# age: 30
# city: New York
# 函數調用中使用 ** 展開
info = {"name": "Bob", "age": 25, "city": "London"}
print_info(**info) # 相當於 print_info(name="Bob", age=25, city="London")
# 輸出同上
3. 同時使用 * 和 **
- 在函數定義中:可以同時使用
*args和**kwargs,以處理不定數量的位置參數和關鍵字參數。
- 順序必須是:固定位置參數 →
*args→ 固定關鍵字參數 →**kwargs。 - 這允許函數非常靈活,能接受各種參數組合。
- 在函數調用中:可以同時使用
*展開位置參數和**展開關鍵字參數。
- 語法:
func(*iterable, **dictionary) - 注意:展開的位置參數必須在關鍵字參數之前(Python的調用規則)。
- 原理:在定義中,
*和**允許函數“捕獲”額外參數;在調用中,它們允許“注入”參數。這常用於裝飾器、API函數或需要轉發參數的場景。
詳細代碼示例:同時使用 * 和 **(定義和調用)
# 示例1: 函數定義中同時使用 * 和 **
def flexible_func(a, b, *args, **kwargs):
print(f"固定位置參數: a={a}, b={b}")
print(f"可變位置參數 (*args): {args}") # 元組
print(f"可變關鍵字參數 (**kwargs): {kwargs}") # 字典
# 可以進一步處理args和kwargs
total = a + b + sum(args)
for key, value in kwargs.items():
print(f"額外信息: {key} = {value}")
return total
# 調用方式1: 直接傳入參數
result = flexible_func(1, 2, 3, 4, name="Alice", age=30)
print(f"結果: {result}")
# 輸出:
# 固定位置參數: a=1, b=2
# 可變位置參數 (*args): (3, 4)
# 可變關鍵字參數 (**kwargs): {'name': 'Alice', 'age': 30}
# 額外信息: name = Alice
# 額外信息: age = 30
# 結果: 10 (1+2+3+4)
# 調用方式2: 使用 * 和 ** 展開傳入
pos_args = [1, 2, 3, 4] # 列表作為位置參數
kw_args = {"name": "Bob", "age": 25} # 字典作為關鍵字參數
result = flexible_func(*pos_args, **kw_args) # 相當於 flexible_func(1, 2, 3, 4, name="Bob", age=25)
print(f"結果: {result}")
# 輸出同上,但 kwargs={'name': 'Bob', 'age': 25},結果仍為10
# 示例2: 更復雜的場景(參數轉發)
def wrapper_func(*args, **kwargs):
# 將所有參數轉發給另一個函數
return flexible_func(*args, **kwargs)
# 調用wrapper_func,它會轉發
result = wrapper_func(5, 6, 7, city="Tokyo", country="Japan")
print(f"結果: {result}")
# 輸出:
# 固定位置參數: a=5, b=6
# 可變位置參數 (*args): (7,)
# 可變關鍵字參數 (**kwargs): {'city': 'Tokyo', 'country': 'Japan'}
# 額外信息: city = Tokyo
# 額外信息: country = Japan
# 結果: 18 (5+6+7)
另一個綜合示例:混合固定參數和可變參數
def order_food(main_dish, *sides, **options):
print(f"主菜: {main_dish}")
print(f"配菜: {sides}")
print(f"選項: {options}")
# 直接調用
order_food("Pizza", "Fries", "Salad", size="Large", drink="Coke")
# 輸出:
# 主菜: Pizza
# 配菜: ('Fries', 'Salad')
# 選項: {'size': 'Large', 'drink': 'Coke'}
# 展開調用
sides_list = ["Fries", "Salad"]
options_dict = {"size": "Large", "drink": "Coke"}
order_food("Pizza", *sides_list, **options_dict) # 同上輸出
注意事項
- 順序規則:
- 定義時:位置參數 →
*args→ 關鍵字參數 →**kwargs。 - 調用時:位置參數(包括
*展開)必須在關鍵字參數(包括**展開)之前。
- Python版本差異:Python 3.5+ 支持更多靈活性,如僅位置參數(
/)和僅關鍵字參數(*),但基本用法不變。 - 常見錯誤:
- 如果
*args接收到關鍵字參數,會報錯(TypeError)。 - 展開時,確保iterable是可迭代的,dictionary的鍵必須是字符串。
- 不要在定義中重複使用
*或**(如兩個*args)。
- 實際應用:常用於庫函數(如
print(*objects, sep=' '))、裝飾器或需要處理未知參數的函數。
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。