Python 擴充之 *args & **kwargs

Python空間發表於2019-01-07

寫在之前

我們在昨天的文章中(零基礎學習 Python 之函式)所寫的函式,它們的引數的個數都是確定的,我們知道世界是不確定的,那麼函式的引數當然也有不固定的時候,那麼當我們碰到這個問題的時候,該怎麼解決呢?請看接下來的文章。

*args

如果你之前學過 C 或者 C++,看到星號的第一反應可能會認為這個與指標相關,然後就開始方了,其實放寬心,Python 中是沒有指標這個概念的。

在 Python 中我們使用星號收集位置引數,請看下面的例子:

>>> def fun(x,*args):
...    print(x)
...    res = x
...    print(args)
...    for i in args:
...            res += i
...    return res
... 
>>> print(fun(1,2,3,4,5,6))
複製程式碼

上述例子中,函式的引數有兩個,但是我們在輸出的時候賦給函式的引數個數不僅僅是兩個,讓我們來執行這個程式碼,得到如下的結果:

1
(2, 3, 4, 5, 6)
21
複製程式碼

從上面我們可以看出,引數 x 得到的值是 1,引數 args 得到的是一個元組 (2,3,4,5,6) ,由此我們可以得出,如果輸入的引數個數不確定,其它的引數全部通過 *args 以元組的方式由 arg 收集起來。

為了更能明顯的看出 *args,我們下面用一個簡單的函式來表示:

>>> def print_args(*args):
...    print(args)
...
複製程式碼

接下來我傳入不同的值,通過引數 *args 得到的結果我們來看一下:

>>> print_args(1,2,3)
(1, 2, 3)
>>> print_args('abc','def','ghi')
('abc', 'def', 'ghi')
>>> print_args('abc',['a','b','c'],1,2,3)
('abc', ['a', 'b', 'c'], 1, 2, 3)
複製程式碼

不管是什麼,都可以一股腦的塞進元組裡,即使只有一個值,也是用元組收集,所以還記得在元組裡一個元素的時候的形式嗎?元組中如果只有一個元素,該元素的後面要有一個逗號。

那麼如果不給 *args 傳值呢?

>>> def print_args(*args):
...    print(args)
... 
>>> print_args()
()
複製程式碼

答案就是這時候 *args 收集到的是一個空的元組。

最後提醒一點的是,當使用星號的時候,不一定要把元組引數命名為 args,但這個是 Python 中的一個常見做法。

**kwargs

使用兩個星號是收集關鍵字引數,可以將引數收集到一個字典中,引數的名字是字典的 “鍵”,對應的引數的值是字典的 “值”。請看下面的例子:

>>> def print_kwargs(**kwargs):
...    print(kwargs)
... 
>>> print_kwargs(a = 'lee',b = 'sir',c = 'man')
{'a': 'lee', 'b': 'sir', 'c': 'man'}
複製程式碼

由例子可以看出,在函式內部,kwargs 是一個字典。

看到這的時候,可能聰明的你會想,引數不是具有不確定型嗎?如何知道引數到底會用什麼樣的方式傳值?其實這個很好辦,把 *args 和 **kwargs 綜合起來就好了啊,請看下面的操作:

>>> def print_all(x,y,*args,**kwargs):
...    print(x)
...    print(y)
...    print(args)
...    print(kwargs)
... 
>>> print_all('lee',1234)
lee
1234
()
{}
>>> print_all('lee',1,2,3,4,5)
lee
1
(2, 3, 4, 5)
{}
>>> print_all('lee',1,2,3,4,5,like = 'python')
lee
1
(2, 3, 4, 5)
{'like': 'python'}
複製程式碼

如此這般,我們就可以應對各種各樣奇葩無聊的引數請求了。當然在這還是要說的是,這裡的關鍵字引數命名不一定要是 kwargs,但這個是通常做法。

寫在最後

更多內容,歡迎關注公眾號「Python空間」,期待和你的交流。

在這裡插入圖片描述

相關文章