Python 的可變參數

Jemmy Lin
4 min readMay 25, 2017

--

最近在看 Python 的原始碼時,常常會看到類似 *args 以及 **kwargs 的字樣,查了一下才發現這是 Python 很貼心的地方,趁機記錄一下

Python 語言有一個很強的功能,就是可以接受不定數量的可變參數。以下舉幾個例子示範其特性

固定參數

def test(var):
print(str(var))

test('abc')
>>> abc

上面這是最一般的寫法,即固定參數數量,一進一出。這應該沒什麼問題。

不固定且不帶識別名的參數

def test(*args):
for
m in args:
print('args > ' + str(m))

aa = ('uuu', 3, 7)
test(*aa)
>>> args > uuu
>>> args > 3
>>> args > 7

當參數前面加一顆 * ,即代表接受了一個 tuple 參數,此即為不定數量的參數使用方法。

不固定且具識別名的參數

def test(**kargs):
for
n in kargs:
print('kargs:' + str(n) + ' > ' + str(kargs[n]))

bb = {'c': 6, 'oo': 'pp', '22': 'vv'}
test(**bb)
>>> kargs:oo > pp
>>> kargs:22 > vv
>>> kargs:c > 6

當參數前面加了 ** 之後,此參數即可視為非固定數量的 Dictionary,那既然是字典類型的話,當然就是具名,因此可直接使用 key / value 的處理方式。

參數優先順序

函式的參數裡若要放進此三種參數的話,是需要依照一定的優先順序來放置的。順序為 var > *args > *kwargs。類似下面這樣

def test(var, *args, **kargs):
print(str(var))

for
m in args:
print('args:' + str(m))

for
n in kargs:
print('kargs:' + str(n) + ' > ' + str(kargs[n]))

aa = ('t', 7, 'yy')
bb = {'c': 6, 'oo': 'pp', '22': 'vv'}

test(4, *aa, **bb)
>>> 4
>>> args:t
>>> args:7
>>> args:yy
>>> kargs:c > 6
>>> kargs:oo > pp
>>> kargs:22 > vv

此時可把固定參數去掉,會發現 tuple 會自動取代固定參數值

def test(var, *args, **kargs):
print(str(var))

for
m in args:
print('args:' + str(m))

for
n in kargs:
print('kargs:' + str(n) + ' > ' + str(kargs[n]))

aa = ('t', 7, 'yy')
bb = {'c': 6, 'oo': 'pp', '22': 'vv'}

test(*aa, **bb)
>>> t
>>> args:7
>>> args:yy
>>> kargs:c > 6
>>> kargs:oo > pp
>>> kargs:22 > vv

這樣子沒什麼問題,但若是直接將 **kargs 與 *args 互換的話,就會發生錯誤

def test(*args, **kargs):
for
m in args:
print('args:' + str(m))

for
n in kargs:
print('kargs:' + str(n) + ' > ' + str(kargs[n]))

aa = ('t', 7, 'yy')
bb = {'c': 6, 'oo': 'pp', '22': 'vv'}

test(**bb, *aa)
>>> test(**bb, *aa)
^

>>> SyntaxError: iterable argument unpacking follows keyword argument unpacking

或是直接在函式中的參數順序對調

def test(**kargs, *args):
for
m in args:
print('args:' + str(m))

for
n in kargs:
print('kargs:' + str(n) + ' > ' + str(kargs[n]))

aa = ('t', 7, 'yy')
bb = {'c': 6, 'oo': 'pp', '22': 'vv'}

test(**bb, *aa)
>>> def test(**kargs, *args):
^
>>> SyntaxError: invalid syntax

這樣也是不行的

以上的示例說明了這三種參數類型使用上的順序,如果善加利用的話也是可以省下很多程式上的構思時間

--

--