Python函式的各種引數(含星號引數)
Python函式的各種引數(含星號引數)
Python中函式的引數有4種形式,分別是:
位置或關鍵字引數(Positional-or-keyword parameter)
僅位置的引數(Positional-only parameter)
任意數量的位置引數(var-positional parameter)
任意數量的關鍵字引數(var-keyword parameter)
第一種:位置或關鍵字引數
這種引數是Python中預設的引數型別,定義這種引數後,可以通過位置引數,或者關鍵字引數的形式傳遞引數:
## 位置或者關鍵字引數 ## 這個是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的很多內建的函式上:
## 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
第三種:任意數量的位置引數(帶單個星號引數)
任意數量的位置引數在定義的時候是需要一個星號字首來表示,在傳遞引數的時候,可以在原有引數的後面新增任意多個引數,這些引數將會被放在元組內提供給函式(方法):
## 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)
第四種:任意數量的關鍵字引數(帶兩個星號引數)
任意數量的關鍵字引數在定義的時候,引數名稱前面需要有兩個星號(**)作為字首,這樣定義出來的引數,在傳遞引數的時候,可以在原有的引數後面新增任意多個關鍵字引數,關鍵字引數是使用[引數名稱=引數值]的形式進行傳遞:
## var-keywords parameter
## 定義的時候,需要兩個星號作為字首
def func(arg1, arg2, **kwargs):
print arg1, arg2, kwargs
func("hello", "Dict, values is:", x=2, y=3, z=3)
## hello Dict, values is: {'x': 2, 'y': 3, '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的解析規律進行定義,其中:
位置或關鍵字引數應該在最前面,其中,沒有預設值的應該在有預設值的引數前面
任意數量位置引數應該放在所有位置或關鍵字引數的後面
任意數量關鍵字引數應該放在任意數量位置引數的後面
注意:任意數量位置引數和任意數量關鍵字引數只能在定義中定義一次。
## 各種引數的混合使用例子
## 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
## 可以將例子儲存到parameter.py檔案
## 而後執行python /path/to/parameter.py