Python 的四種共享傳參詳解
Python 唯一支持的參數傳遞方式為共享傳參(call by sharing),傳遞參數一共有四種傳遞方式,分別為:位置參數,默關鍵字參數和可變參數,其中可變參數分為兩種(*args 和 **kargs)。
一、位置參數
函數調用時,參數會根據函數定義的參數位置而自動傳遞。
def func(a, b):
print(a)
print(b)
return a b
>>func("A", "B")
A
B
'AB'
>>func("B", "A")
B
A
'BA'
在上述實例中,我們發現參數的傳遞必須嚴格按照參數的定義位置進行傳遞的,而且函數的參數與調用函數所傳遞的參數數量不一致時,就會引發TypeError。
二、默認參數
函數調用時,為函數的某個參數提供默認值,調用函數時可選擇不傳入改參數的值。
def func(a="B", b):
print(a)
print(b)
return a b
SyntaxError: non-default argument follows default argument
def func(a, b="A"):
print(a)
print(b)
return a b
>>func("A")
A
A
'AA'
>>func("A", "B"):
A
B
"AB"
從上述實例中,我們發現默認參數必須在位置參數的後面。個人認為默認參數是位置參數的一種缺省形式。這也可以解釋為何默認參數必須在位置參數的後面。
三、關鍵字參數
在進行函數調用時,使用 "參數名"="值" 的形式進行參數指定。清除位置參數在調用時的順序要求。
def func(a, b):
print(a)
print(b)
return a b
>>func(b="B", a="A")
A
B
"AB"
def func(a, b="B"):
print(a)
print(b)
return a b
>>func(a="A")
A
B
'AB'
>>func(a="A", b="C"):
A
B
'AC'
從上述實例可以看出,雖然函數定義時按照位置參的形式定義的,但是依然可以在調用的時候可以使用關鍵字參數來進行指定,如果函數定義時有默認參數,則依然可以選擇缺省或者傳入。
四、可變參數
可變參數是指在函數定義時使用 *args (*加參數名)和 **kargs (**加參數名)的形式作為參數,在函數調用時就可以傳入多個參數,會在實際工程中更加靈活,其中 *args 對應着傳入多個位置參數,**kargs 對應傳入多個關鍵字參數。
def func(*args):
print(type(args))
print(args)
for i in args:
print(i)
>>func("A", "B")
('A', 'B')
A
B
>>> func()
()
從上述實例中可以看出,可變參數 *args 在使用時可以自由選擇位置參數個數,在函數使用時,函數會自動生成一個元組 (tuple) 來放置位置參數,我們在定義函數的時候只需要操作對應的元組即可,注意一個小細節,為何要使用元組?這實際上也對應了位置參數的位置不可變性。
def func(**kargs):
print(type(kargs))
print(args)
for key, value in kargs.items():
print("%s : %s" % (key,value) )
>>> func(a="A", b="B")
{'a': 'A', 'b': 'B'}
a : A
b : B
>>> func(b="B", a="A")
{'b': 'B', 'a': 'A'}
b : B
a : A
>>> func()
{}
從上述實例可以看出,可變參數 **kargs 使用時也可以自由選擇關鍵字參數的個數,在函數使用時,函數會生成一個字典(dict)來放置關鍵字參數,我們在定義函數時只需要操作對應的字典字典即可,同樣注意一個小細節,為何是使用字典?這同樣也對應了關鍵字參數的位置可變性。
五、四種參數的混用
我們在實際應用中,經常會用到這幾種參數的搭配使用,下面通過一個例子來解釋這四種參數的混用情況。
def func(a, b="B", *args, c,**kargs):
print(a)
print(b)
print(*args)
print(c)
print(kargs)
>>> func("A", "X", "Z", c="CC", d="DD", f="FF")
A
X
Z
CC
{'d': 'DD', 'f': 'FF'}
>>> func("A",c="CC")
A
B
CC
{}
從上述實例中可以看出,我們在混用時主要遵循兩個原則
1.在函數定義時,順序為(位置參數,默認參數,*args 可變參數,關鍵字參數, **kargs 可變參數)。
2.在調用時,位置參數和關鍵參數一定要有,不可缺省,可變參數可以缺省。特別注意,如果定義了默認參數,又定義了 *args 可變參數,需注意位置參數的個數,因為函數調用默認會先識別默認參數。上述實例中就有這種情況。