Python中函數的參數有4種形式,分別是:
位置或關鍵字參數(Positional-or-keyword parameter)
僅位置的參數(Positional-only parameter)
任意數量的位置參數(var-positional parameter)
任意數量的關鍵字參數(var-keyword parameter)
第一種:位置或關鍵字參數
這種參數是Python中默認的參數類型,定義這種參數後,可以通過位置參數,或者關鍵字參數的形式傳遞參數:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ## 位置或者關鍵字參數 ## 這個是Python的默認參數類型 ## 示例:arg2提供了默認value def func(arg1, arg2 = "World!" ): print arg1, arg2 ## func可以通過位置參數形式調用 func( "Hello" , "MitchellChu" ) ## 也可以通過關鍵字參數的形式來調用func func(arg1 = "Hello" , arg2 = "World!" ) ## 當然,混合的方式也是完全沒有問題的 func( "Hello" , arg2 = "World!" ) ## 不過如果你不能將關鍵字參數優先於位置參數傳遞給函數(方法) ## 這個調用方法是不能接受的,因爲優先級不一樣.後面會說 func(arg1 = "Hello" , "World!" ) ## ERROR |
第二種方式:僅適用位置參數的形式
這種形式在需要將參數傳遞給函數(方法)時,僅能通過位置參數的傳遞方式。這種形式對於Python的開發者來說,暫時並沒有辦法使用。這種形式現在僅存在Python的很多內建的函數上:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ## Positional-only parameter has no syntax to define ## 雖然無定義方法,但內建的很多函數都是僅接受位置參數的 abs ( - 3 ) ## correct abs (a = 3 ) ## wrong ## Traceback (most recent call last): ## File "<stdin>", line 1, in <module> ## TypeError: abs() takes no keyword arguments pow (x = 2 ,y = 3 ) ## Traceback (most recent call last): ## File "<stdin>", line 1, in <module> ## TypeError: pow() takes no keyword arguments pow ( 2 , 3 ) ## 8 |
第三種:任意數量的位置參數(帶單個星號參數)
任意數量的位置參數在定義的時候是需要一個星號前綴來表示,在傳遞參數的時候,可以在原有參數的後面添加任意多個參數,這些參數將會被放在元組內提供給函數(方法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | ## var-positional parameter ## 定義的時候,我們需要添加單個星號作爲前綴 def func(arg1, arg2, * args): print arg1, arg2, args ## 調用的時候,前面兩個必須在前面 ## 前兩個參數是位置或關鍵字參數的形式 ## 所以你可以使用這種參數的任一合法的傳遞方法 func( "hello" , "Tuple, values is:" , 2 , 3 , 3 , 4 ) ## Output: ## hello Tuple, values is: (2, 3, 3, 4) ## 多餘的參數將自動被放入元組中提供給函數使用 ## 如果你需要傳遞元組給函數 ## 你需要在傳遞的過程中添加*號 ## 請看下面例子中的輸出差異: func( "hello" , "Tuple, values is:" , ( 2 , 3 , 3 , 4 )) ## Output: ## hello Tuple, values is: ((2, 3, 3, 4),) func( "hello" , "Tuple, values is:" , * ( 2 , 3 , 3 , 4 )) ## Output: ## hello Tuple, values is: (2, 3, 3, 4) |
第四種:任意數量的關鍵字參數(帶兩個星號參數)
任意數量的關鍵字參數在定義的時候,參數名稱前面需要有兩個星號(**)作爲前綴,這樣定義出來的參數,在傳遞參數的時候,可以在原有的參數後面添加任意多個關鍵字參數,關鍵字參數是使用[參數名稱=參數值
]的形式進行傳遞:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ## var-keywords parameter ## 定義的時候,需要兩個星號作爲前綴 def func(arg1, arg2, * * kwargs): print arg1, arg2, kwargs func( "hello" , "Dict, values is:" , x = 2 , y = 3 , z = 3 ) ## Output: ## 多餘的參數將自動被放入字典中提供給函數使用 ## 如果你需要直接傳遞字典給函數 ## 你需要在傳遞的過程中添加** ## 此時如果還有關鍵字參數應在字典前提供完成 ## 不能在字典後再提供 ## 請看下面例子中的輸出差異: func( "hello" , "Dict., values is:" , * * { 'x' : 2 , 'y' : 3 , 'z' : 3 }) ## hello Dict., values is: {'y': 3, 'x': 2, 'z': 3} func( "hello" , "Dict., values is:" , * * { 'x' : 2 , 'y' : 3 , 'z' : 3 ,}) ## hello Dict., values is: {'y': 3, 'x': 2, 'z': 3} func( "hello" , "Dict., values is:" , { 'x' : 2 , 'y' : 3 , 'z' : 3 }) ## Traceback (most recent call last): ## File "<stdin>", line 1, in <module> ## TypeError: func() takes exactly 2 arguments (3 given) func( "hello" , "Dict., values is:" , s = 3 , * * { 'x' : 2 , 'y' : 3 , 'z' : 3 ,}) ## hello Dict., values is: {'y': 3, 'x': 2, 's': 3, 'z': 3} ## 提供了重複的參數 func( "hello" , "Dict., values is:" , y = 3 , * * { 'x' : 2 , 'y' : 3 , 'z' : 3 ,}) ## Traceback (most recent call last): ## File "<stdin>", line 1, in <module> ## TypeError: func() got multiple values for keyword argument 'y' |
總結:四種參數形式中僅有第二種Python沒有提供定義的方法,其他三種在定義的時候也需要注意,定義的時候應該根據Python的解析規律進行定義,其中:
位置或關鍵字參數應該在最前面,其中,沒有默認值的應該在有默認值的參數前面
任意數量位置參數應該放在所有位置或關鍵字參數的後面
任意數量關鍵字參數應該放在任意數量位置參數的後面
注意:任意數量位置參數和任意數量關鍵字參數只能在定義中定義一次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | ## 各種參數的混合使用例子 ## Author: MitchellChu def func(arg1, arg2 = 'default' , * args, * * kwargs): print "arg1=%s, arg2=%s, args=%s, kwargs=%s" % (arg1, arg2, args, kwargs) func( 1 ) ## correct func( 1 , 2 ) ## correct func( 1 , 2 , 3 , 4 ) ## correct func( 1 , 2 , 3 , 4 ,x = 1 ,y = 2 ) ## correct func( 1 , 2 ,x = 1 ) ## correct func(x = 1 ) ## wrong func(arg1 = 1 ) ## correct func( 1 ,x = 1 ) ## correct |
func(arg1, arg2=, *args, **kwargs): (% (arg1, arg2, args, kwargs)) func(,,,=,=,=,=)
arg1=1, arg2=2, args=(3,), kwargs={'a': 4, 'x': 1, 'z': 3, 'y': 2}