Python中魔法參數(shù)?*args?和?**kwargs使用詳細(xì)講解
在Python編程中,函數(shù)的靈活性是其強(qiáng)大之處之一。其中,*args 和 **kwargs 是實(shí)現(xiàn)函數(shù)參數(shù)可變性的重要工具。

無論我們是Python初學(xué)者還是經(jīng)驗(yàn)豐富的開發(fā)者,充分理解這兩個(gè)概念都有助于編寫更加靈活、高效的代碼。
本文將深入探討*args和**kwargs的用法、原理和應(yīng)用場景,以全面掌握它們。
一、初識(shí) *args 和 **kwargs
*args 和 **kwargs 都是python中的可變參數(shù)。
*args可以用來表示任何多個(gè)無名參數(shù),本質(zhì)上是元組類型。
**kwargs可以用來表示關(guān)鍵字參數(shù),本質(zhì)上是字典類型。

1. 什么是 *args?
*args 允許函數(shù)接受任意數(shù)量的位置參數(shù),這些參數(shù)會(huì)以元組的形式傳入函數(shù)內(nèi)部。
args是“arguments”(參數(shù))的縮寫,但名稱并非固定,關(guān)鍵在于星號*。
示例:
def sum_numbers(*args):
total = 0
for number in args:
total += number
return total
print(sum_numbers(1, 2, 3)) # 輸出:6
2. 什么是 **kwargs?
**kwargs 允許函數(shù)接受任意數(shù)量的關(guān)鍵字參數(shù),這些參數(shù)會(huì)以字典的形式傳入函數(shù)內(nèi)部。
kwargs是“keyword arguments”(關(guān)鍵字參數(shù))的縮寫,同樣,名稱不固定,關(guān)鍵在于雙星號**。
示例:
def greet(**kwargs):
for key, value in kwargs.items():
print(f"{key} = {value}")
greet(name='Alice', age=30)
# 輸出:
# name = Alice
# age = 30
二、深入理解 *args
1. 使用場景
參數(shù)數(shù)量未知:當(dāng)您定義的函數(shù)需要接受不定數(shù)量的位置參數(shù)時(shí),*args非常有用。
函數(shù)包裝器:在編寫裝飾器或高階函數(shù)時(shí),需要傳遞參數(shù)給被裝飾函數(shù)。
2. 工作原理
當(dāng)函數(shù)定義中包含*args時(shí),傳入的所有位置參數(shù)都會(huì)被收集到一個(gè)元組中,您可以像處理元組一樣處理args。
示例:
def display_args(first_arg, *args):
print("第一個(gè)參數(shù):", first_arg)
print("其他參數(shù):", args)
display_args(10, 20, 30, 40)
# 輸出:
# 第一個(gè)參數(shù): 10
# 其他參數(shù): (20, 30, 40)
3. 注意事項(xiàng)
*args必須放在函數(shù)定義參數(shù)列表的最后,除非還有**kwargs。
在調(diào)用函數(shù)時(shí),不能使用關(guān)鍵字參數(shù)傳遞給*args。
三、深入理解 **kwargs
1. 使用場景
參數(shù)名未知:當(dāng)函數(shù)需要接受任意數(shù)量的關(guān)鍵字參數(shù),且參數(shù)名在定義時(shí)未知。
配置參數(shù):處理配置項(xiàng)或可選參數(shù)。
2. 工作原理
函數(shù)定義中包含**kwargs時(shí),所有的關(guān)鍵字參數(shù)都會(huì)被收集到一個(gè)字典中,您可以像處理字典一樣處理kwargs。
示例:
def display_kwargs(**kwargs):
for key, value in kwargs.items():
print(f"{key} : {value}")
display_kwargs(name='祖沖之', age=25, country='China')
# 輸出:
# name : 祖沖之
# age : 25
# country : China
3. 注意事項(xiàng)
**kwargs必須放在函數(shù)定義參數(shù)列表的最后。
在函數(shù)調(diào)用時(shí),關(guān)鍵字參數(shù)的名稱必須是有效的Python標(biāo)識(shí)符。
四、同時(shí)使用 *args 和 **kwargs
1. 函數(shù)定義順序
在函數(shù)定義中,參數(shù)的順序必須為:
位置參數(shù)(必需參數(shù))
默認(rèn)參數(shù)(可選參數(shù))
*args(可變位置參數(shù))
**kwargs(可變關(guān)鍵字參數(shù))
示例:
def func(a, b=2, *args, **kwargs):
print("a =", a)
print("b =", b)
print("args =", args)
print("kwargs =", kwargs)
func(1, 3, 5, 7, x=10, y=20)
# 輸出:
# a = 1
# b = 3
# args = (5, 7)
# kwargs = {'x': 10, 'y': 20}
2. 應(yīng)用場景
最大化函數(shù)的靈活性:允許函數(shù)接受任意類型和數(shù)量的參數(shù)。
編寫通用代碼:如裝飾器、日志記錄器等,需要處理不同的函數(shù)簽名。
五、參數(shù)解包與傳遞
1. 位置參數(shù)的解包(*)
將序列(如列表、元組)中的元素解包為單獨(dú)的參數(shù)傳遞給函數(shù)。
示例:
def add(a, b, c):
return a + b + c
numbers = [1, 2, 3]
result = add(*numbers) # 等價(jià)于 add(1, 2, 3)
print(result) # 輸出:6
2. 關(guān)鍵字參數(shù)的解包(**)
將字典中的鍵值對解包為關(guān)鍵字參數(shù)傳遞給函數(shù)。
示例:
def introduce(name, age, country):
print(f"我叫{name},今年{age}歲,來自{country}。")
info = {'name': 'Charlie', 'age': 28, 'country': 'China'}
introduce(**info)
# 輸出:我叫Charlie,今年28歲,來自China。
3. 同時(shí)解包
示例:
def func(a, b, c, d):
print(a, b, c, d)
args = (1, 2)
kwargs = {'c': 3, 'd': 4}
func(*args, **kwargs)
# 輸出:1 2 3 4
六、在裝飾器中的應(yīng)用
1. 為什么在裝飾器中使用?
裝飾器需要能夠裝飾任意函數(shù),無論其參數(shù)如何定義。
使用*args和**kwargs,可以編寫一個(gè)通用的裝飾器,適用于所有函數(shù)。
2. 編寫通用裝飾器
示例:
def logger(fn):
def wrapper(*args, **kwargs):
print(f"正在調(diào)用函數(shù) {fn.__name__},參數(shù):args={args}, kwargs={kwargs}")
result = fn(*args, **kwargs)
print(f"函數(shù) {fn.__name__} 調(diào)用完畢,返回值:{result}")
return result
return wrapper
@logger
def multiply(a, b):
return a * b
@logger
def greet(name, message='Hello'):
return f"{message}, {name}!"
multiply(3, 4)
# 輸出:
# 正在調(diào)用函數(shù) multiply,參數(shù):args=(3, 4), kwargs={}
# 函數(shù) multiply 調(diào)用完畢,返回值:12
greet(name='Alice')
# 輸出:
# 正在調(diào)用函數(shù) greet,參數(shù):args=(), kwargs={'name': 'Alice'}
# 函數(shù) greet 調(diào)用完畢,返回值:Hello, Alice!
3. 深入理解
*args和**kwargs的傳遞:裝飾器內(nèi)部的wrapper函數(shù)接受*args和**kwargs,并將其傳遞給被裝飾的函數(shù)fn。
保持函數(shù)簽名:這樣,裝飾器不會(huì)改變原函數(shù)的參數(shù)要求。
七、實(shí)際應(yīng)用案例
1. 參數(shù)校驗(yàn)
使用*args和**kwargs,可以編寫裝飾器來檢查參數(shù)的類型或值。
示例:
def type_check(fn):
def wrapper(*args, **kwargs):
for arg in args:
if not isinstance(arg, int):
raise TypeError("所有參數(shù)必須是整數(shù)")
return fn(*args, **kwargs)
return wrapper
@type_check
def add_integers(*args):
return sum(args)
print(add_integers(1, 2, 3)) # 輸出:6
# add_integers(1, '2', 3) # 拋出 TypeError: 所有參數(shù)必須是整數(shù)
2. 緩存函數(shù)結(jié)果(Memoization)
示例:
def memoize(fn):
cache = {}
def wrapper(*args):
if args in cache:
return cache[args]
result = fn(*args)
cache[args] = result
return result
return wrapper
@memoize
def fibonacci(n):
if n <= 2:
return 1
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 輸出:55
3. 統(tǒng)一接口的API設(shè)計(jì)
設(shè)計(jì)可接受各種參數(shù)的API,提高靈活性。
示例:
def api_request(endpoint, *args, **kwargs):
url = f"https://api.example.com/{endpoint}"
print(f"請求URL:{url}")
print(f"位置參數(shù):{args}")
print(f"關(guān)鍵字參數(shù):{kwargs}")
# 這里可以添加實(shí)際的請求邏輯
api_request('get-data', 1, 2, key='value', token='abcd1234')
# 輸出:
# 請求URL:https://api.example.com/get-data
# 位置參數(shù):(1, 2)
# 關(guān)鍵字參數(shù):{'key': 'value', 'token': 'abcd1234'}
八、總結(jié)
靈活性: *args和**kwargs使函數(shù)能夠接受可變數(shù)量和類型的參數(shù),增加了函數(shù)的靈活性。
代碼復(fù)用: 在裝飾器和高階函數(shù)中使用,能編寫更加通用的代碼。
注意事項(xiàng): 使用時(shí)要注意參數(shù)的順序和解包的正確性,避免參數(shù)沖突。
通過深入理解和靈活運(yùn)用*args和**kwargs,我們可以編寫出更加高效、靈活的Python代碼。
到此這篇關(guān)于Python中魔法參數(shù) *args 和 **kwargs使用詳細(xì)講解的文章就介紹到這了,更多相關(guān)Python魔法參數(shù) *args 和 **kwargs內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python?pytorch實(shí)現(xiàn)繪制一維熱力圖
熱力圖是非常特殊的一種圖,可以顯示不可點(diǎn)擊區(qū)域發(fā)生的事情,這篇文章主要為大家介紹了如何利用pytorch實(shí)現(xiàn)繪制一維熱力圖,感興趣的可以了解一下2023-05-05
Python利用Matplotlib繪圖無法顯示中文字體的兩種解決方案
matplotlib 是python最著名的繪圖庫,它提供了一整套和matlab相似的命令A(yù)PI,這篇文章主要給大家介紹了關(guān)于Python利用Matplotlib繪圖無法顯示中文字體的兩種解決方案,需要的朋友可以參考下2024-03-03
Python實(shí)現(xiàn)獲取操作系統(tǒng)版本信息方法
這篇文章主要介紹了Python實(shí)現(xiàn)獲取操作系統(tǒng)版本信息方法,本文在命令行中獲取操作系統(tǒng)信息,介紹了platform模塊的使用,需要的朋友可以參考下2015-04-04
利用python對mysql表做全局模糊搜索并分頁實(shí)例
這篇文章主要介紹了利用python對mysql表做全局模糊搜索并分頁實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
在django中,關(guān)于session的通用設(shè)置方法
今天小編就為大家分享一篇在django中,關(guān)于session的通用設(shè)置方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08

