在看開源碼的時候,很容易看到像這樣的function parameter,附帶一個星號的參數 *args ,或是附帶兩個星號的參數 **kwargs,這是python 裡面很常用的語法,可以讓python接收任意數量的參數
def foo(param1, *args, **kwargs): # 順序不可對調!! pass
*args : 可變的參數串列(positional arguments),所謂的"可變",也就代表著呼叫該function時,我們可以完全忽略他,不帶任何參數;亦或者是一次給他多個參數。
def foo(param1, *args): pass
舉例來說,下面的 foo() 接收一個必要的參數param1,以及一個可變長度的*args,它會幫你把輸入的參數打包(pack)成為一個 tuple,讓你的參數數量要多長就有多長。
def foo(param1, *args): print 'Required argument : ', param1 for v in args: print 'Optional arguments : ', v foo(0) # Required argument : 0 foo(0, 'a', 'b', 'c') # Required argument : 0 # Optional arguments : a # Optional arguments : b # Optional arguments : c
**kwargs : 可變的字典列表( keyword arguments ),顧名思義,它其實就是一個dict,使用起來就會比前面的*args更為易讀,清楚了!!
def foo(param1, **kwargs): pass
在function裡面的用法,就跟一般使用dict差不多,不過呼叫的方式則是跟一般具名參數呼叫的方法一樣。
def foo(param1, **kwargs): print 'Required argument : ', param1 for k, v in kwargs.items(): print 'Optional arguments :', k, v foo(0) # Required argument : 0 foo(0, name='San', age=18, height=168) # Required argument : 0 # Optional arguments : age 18 # Optional arguments : name San # Optional arguments : height 168
既然可以放在Function call的引數上面,那可不可以放在其他地方呢?
當然是可以的,接下來就來看類似的用法,但是我們把它放 function call 裡面,這時候他就會自動幫我們展開每一個參數囉!!
def foo(param1, *args, **kwargs): print 'Input : ', param1 print 'args:', args print 'kwargs:', kwargs # === Put tuple / list / dict to function call === my_tuple = (1,2) foo('*my_tuple', *my_tuple) # Input : *my_tuple # args: (1, 2) # kwargs: {} my_list = [1,2] foo('*my_list', *my_list) # Input : *my_list # args: (1, 2) # kwargs: {} my_dict = {'a':1,'b':2} foo('**my_dict',**my_dict) # Input : **my_dict # args: () # kwargs: {'a': 1, 'b': 2}
Stackoverflow 裡面就有人下了一個很棒的總結,並且附上一張表,完整的詮釋與應用我上面所說的一切!!
1. 在 function call 裡面,* 用來將一個 tuple 或是 list 展開成為 positional 或是keyword參數,送進給該function.
2. 在 function call 裡面,** 用來將一個 dictionary展開成為positional 或是keyword參數,送進給該function.
3 .在 function construction 上,* 將 positional 參數打包成為tuple。
4. 在 function construction 上,** 將 keyword 參數打包成為dictionary.
In function *construction* In function *call* ======================================================================= | def f(*args): | def f(a, b): *args | for arg in args: | return a + b | print(arg) | args = (1, 2) | f(1, 2) | f(*args) ----------|--------------------------------|--------------------------- | def f(a, b): | def f(a, b): **kwargs | return a + b | return a + b | def g(**kwargs): | kwargs = dict(a=1, b=2) | return f(**kwargs) | f(**kwargs) | g(a=1, b=2) | -----------------------------------------------------------------------
留言列表