剛學用Python的時候,特別是看一些庫的源碼時,常常會看到func(*args, **kwargs)這樣的函數定義,這個*和**讓人有點費解。其實只要把函數參數定義搞清楚了,就不難理解了。函數
先說說函數定義,咱們都知道,下面的代碼定義了一個函數funcAspa
def funcA():
pass
顯然,函數funcA沒有參數(同時啥也不幹:D)。對象
下面這個函數funcB就有兩個參數了,
def funcB(a, b):
print a
print b
調用的時候,咱們須要使用函數名,加上圓括號擴起來的參數列表,好比 funcB(100, 99),執行結果是:
100
99
很明顯,參數的順序和個數要和函數定義中一致,若是執行funcB(100),Python會報錯的:
TypeError: funcB() takes exactly 2 arguments (1 given)源碼
咱們能夠在函數定義中使用參數默認值,好比
def funcC(a, b=0):
print a
print b
在函數funcC的定義中,參數b有默認值,是一個可選參數,若是咱們調用funcC(100),b會自動賦值爲0。it
OK,目前爲止,咱們要定義一個函數的時候,必需要預先定義這個函數須要多少個參數(或者說能夠接受多少個參數)。通常狀況下這是沒問題的,可是也有在定義函數的時候,不能知道參數個數的狀況(想想C語言裏的printf函數),在Python裏,帶*的參數就是用來接受可變數量參數的。看一個例子
def funcD(a, b, *c):
print a
print b
print "length of c is: %d " % len(c)
print c
調用funcD(1, 2, 3, 4, 5, 6)結果是
1
2
length of c is: 4
(3, 4, 5, 6)
咱們看到,前面兩個參數被a、b接受了,剩下的4個參數,所有被c接受了,c在這裏是一個tuple。咱們在調用funcD的時候,至少要傳遞2個參數,2個以上的參數,都放到c裏了,若是隻有兩個參數,那麼c就是一個empty tuple。io
好了,一顆星咱們弄清楚了,下面輪到兩顆星。margin
上面的例子裏,調用函數的時候,傳遞的參數都是根據位置來跟函數定義裏的參數表匹配的,好比funcB(100, 99)和funcB(99, 100)的執行結果是不同的。在Python裏,還支持一種用關鍵字參數(keyword argument)調用函數的辦法,也就是在調用函數的時候,明確指定參數值付給那個形參。好比仍是上面的funcB(a, b),咱們經過這兩種方式調用
funcB(a=100, b=99)
和
funcB(b=99, a=100)
結果跟funcB(100, 99)都是同樣的,由於咱們在使用關鍵字參數調用的時候,指定了把100賦值給a,99賦值給b。也就是說,關鍵字參數可讓咱們在調用函數的時候打亂參數傳遞的順序!top
另外,在函數調用中,能夠混合使用基於位置匹配的參數和關鍵字參數,前題是先給出固定位置的參數,好比
def funcE(a, b, c):
print a
print b
print c
調用funcE(100, 99, 98)和調用funcE(100, c=98, b=99)的結果是同樣的。word
好了,通過以上鋪墊,兩顆星總算能夠出場了:
若是一個函數定義中的最後一個形參有 ** (雙星號)前綴,全部正常形參以外的其餘的關鍵字參數都將被放置在一個字典中傳遞給函數,好比:
def funcF(a, **b):
print a
for x in b:
print x + ": " + str(b[x])
調用funcF(100, c='你好', b=200),執行結果
100
c: 你好
b: 200
你們能夠看到,b是一個dict對象實例,它接受了關鍵字參數b和c。dict
常規參數,*參數及**參數能夠同時使用,具體怎麼用?看看Python Reference Manual吧,關於Function definitions的那些章節。其實,笨想也能猜出來啊,o(∩_∩)o...