close

在看開源碼的時候,很容易看到像這樣的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)                   |

-----------------------------------------------------------------------

 

https://stackoverflow.com/questions/36901/what-does-double-star-asterisk-and-star-asterisk-do-for-parameters

 

arrow
arrow
    文章標籤
    python ** * double asterisk
    全站熱搜

    Chris 發表在 痞客邦 留言(1) 人氣()