Python入門系列38 - 關(guān)于 *args,**kwargs 的作用

關(guān)于 *args,**kwargs 的作用
本篇閱讀時間約為 4 分鐘。
1
前言
有時在看在大神寫的程序中,會看見?*args,**kwargs 這樣的寫法,那么你知道,這樣寫法的含義是什么嗎?
本篇用最簡短的小示例來介紹下它們的用法,以及這樣寫的好處。
2
*args 用法
*args:可以理解為多個無名參數(shù),也有人叫可變位置參數(shù)的。
示例1,定義一個打印的函數(shù),傳入任意參數(shù)即可:
def print_func(*args):print(type(args))print(args)print_func(1, 2, '呵呵噠', [])

打印 args 的類型是一個元組。直接對此變量打印輸出,可以看到雖然我們以正常的多個參數(shù)傳入,但是用到 args 時,將外界參數(shù)以元組形式呈現(xiàn)出來。
示例2 ,在打印函數(shù)中的參數(shù)處,新增 x 和 y 變量。
def print_func(x, y, *args):print(type(x))print(x)print(y)print(type(args))????print(args)print_func(1, 2, '呵呵噠', [])

若在函數(shù)參數(shù)定義處,有多個實體變量,它會按照順序一一將傳入的參數(shù)對應(yīng)上,就像上面的例子,1傳入對應(yīng)就是x,2傳入就是y,其余的參數(shù)對應(yīng) *args 。
示例3,若要是將 *args 放在參數(shù)最前面,顛倒順序會如何?
def print_func(*args, x, y):print(type(x))print(x)print(y)print(type(args))print(args)print_func(1, 2, '呵呵噠', [])

可以看到,報錯了,錯誤信息,提示找不到關(guān)鍵詞參數(shù) x,y。
所以若 *args 不是在最后,則需要在參數(shù)傳入時,明確定義 *args 后面的變量參數(shù)名,如下:
def print_func(*args, x, y):print(type(x))print(x)print(y)print(type(args))????print(args)print_func(1, 2, '呵呵噠', [], x='x', y='y')

上面分別介紹了:
1. (x,y,*args) 順序
2. (*args,x,y) 順序
其實還有第三種順序,就是放在中間,至于結(jié)果怎樣?可以自行嘗試,留個小小的懸念,多多動手才能學(xué)到東西,哈哈哈。
3
**kwargs 用法
**kwargs:多個關(guān)鍵詞參數(shù)。
示例1:
def print_func(**kwargs):print(type(kwargs))print(kwargs)print_func(1, 2, '呵呵噠', [])

直接報錯了,大致意思是需要給出四個參數(shù)!
改下調(diào)用函數(shù)時的入?yún)ⅲ?/span>
def print_func(**kwargs):print(type(kwargs))print(kwargs)print_func(a=1, b=2, c='呵呵噠', d=[])

入?yún)r,多添加了關(guān)鍵詞??梢钥吹酱蛴r,kwargs本身是字典類型,將傳入的參數(shù)以字典形式呈現(xiàn)出來。
4
組合使用
arg,*args,**kwargs,三者是可以組合使用的,但是組合使用需要遵循一定的語法規(guī)則,即順序為王。
需要按照:?
arg,*args,**kwargs 作為函數(shù)參數(shù)的順序。
def print_func(x, *args, **kwargs):print(x)print(args)print(kwargs)print_func(1, 2, 3, 4, y=1, a=2, b=3, c=4)

可以看到按照順序,依次進行解析打印。若不按照順序,可自行嘗試,會報錯的喲!
5
優(yōu)點
首先說明一點用*args?和?**kwargs?只是為了方便并沒有強制使用它們。使用這兩個的好處就是使得代碼非常靈活。
當(dāng)你不確定你的函數(shù)里將要傳遞多少參數(shù)時你可以用*args,就像上面的示例中一樣,它可以傳遞任意數(shù)量的參數(shù)。**kwargs允許你使用沒有事先定義的參數(shù)名。
6
你不知道的小知識點
當(dāng)調(diào)用函數(shù)時你也可以用*和**語法.例如:
def print_func(a, b, c):print(f'a = {a}, b = , c = {c}')animal_list = ['pig', 'dog', 'cat']print_func(*animal_list)

正如結(jié)果顯示,它可以傳遞列表(或者元組)的每一項并把它們解包。
注意:入?yún)r必須與它們在函數(shù)里的參數(shù)個數(shù)相吻合,所以你可以在函數(shù)調(diào)用時用*。
同理,**也是相似的:
def print_func(a, b, c):????print(f'a?:?{a},?b?:?,?c?:?{c}')animal_dict = {'a': 'pig', 'b': 'dog', 'c': 'cat'}print_func(**animal_dict)

需要注意:定義的 animal_dict 中,key 必須等于調(diào)用函數(shù)中的變量關(guān)鍵詞,否則會報錯!

7
總結(jié)
本想著,介紹此篇應(yīng)該會很短的內(nèi)容,沒想到寫著寫著又這么多了,總之相信下次再看見 * 和 ** 的你,應(yīng)該不會有逃避心理了!
至此完!

