剛學用python的時候,特別是看一些庫的原始碼時,經常會看到func(*args, **kwargs)這樣的函式定義,這個*和**讓人有點費解。其實只要把函式引數定義搞清楚了,就不難理解了。
先說說函式定義,我們都知道,下面的**定義了乙個函式funca
def funca():
pass
顯然,函式funca沒有引數(同時啥也不幹:d)。
下面這個函式funcb就有兩個引數了,
def funcb(a, b):
print a
print b
呼叫的時候,我們需要使用函式名,加上圓括號擴起來的引數列表,比如 funcb(100, 99),執行結果是:
10099
很明顯,引數的順序和個數要和函式定義中一致,如果執行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。
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)結果是12
length of c is: 4
(3, 4, 5, 6)
我們看到,前面兩個引數被a、b接受了,剩下的4個引數,全部被c接受了,c在這裡是乙個tuple。我們在呼叫funcd的時候,至少要傳遞2個引數,2個以上的引數,都放到c裡了,如果只有兩個引數,那麼c就是乙個empty tuple。
好了,一顆星我們弄清楚了,下面輪到兩顆星。
上面的例子裡,呼叫函式的時候,傳遞的引數都是根據位置來跟函式定義裡的參數列匹配的,比如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。也就是說,關鍵字引數可以讓我們在呼叫函式的時候打亂引數傳遞的順序!
另外,在函式呼叫中,可以混合使用基於位置匹配的引數和關鍵字引數,前題是先給出固定位置的引數,比如
def funce(a, b, c):
print a
print b
print c
呼叫funce(100, 99, 98)和呼叫funce(100, c=98, b=99)的結果是一樣的。
好了,經過以上鋪墊,兩顆星總算可以出場了:
如果乙個函式定義中的最後乙個形參有 ** (雙星號)字首,所有正常形參之外的其他的關鍵字引數都將被放置在乙個字典中傳遞給函式,比如:
def funcf(a, **b):
print a
for x in b:
print x + ": " + str(b[x])
呼叫funcf(100, c='你好', b=200),執行結果
100c: 你好
b: 200
大家可以看到,b是乙個dict物件例項,它接受了關鍵字引數b和c。
同c語言一樣,python中也有可變引數函式,即乙個函式可以接收多個引數,而這些引數的個數在函式呼叫之前事先是不知道的。
在c裡面最典型的例子就是printf函式,同樣在python裡面使用可變引數也可以很方便的實現printf()
**如下:
[python]view plain
copy
defprintf(fmt, *arg):
fmt % arg
printf定義中的*arg就是可變引數,它的型別為tuple,代表了除fmt引數之外的所有傳入引數。
但如果我們傳入的可變引數是字典,那麼*arg的定義就不夠用了,這時我們應該使用**arg來定義函式。
這時我們呼叫函式的方式變為:
定義:def fun(**arg)
fun(key1 = val1, key2=val2, ...)
如: fun(one=1, two=2)
**如下:
[python]view plain
copy
deftestfun1(**arg):
fork
inarg.keys():
printf("arg[%s] = %s."
, k, arg[k])
deftestfun2(*arg1, **arg2):
arg1
arg2
if__name__ ==
'__main__'
: printf("how do you do? %d, %d", 2
, 3)
testfun1(one=1
, two=
2)
testfun2(1, 2
, 3, one=
1, two=
2, three=
3)
輸出結果:
how do you do? 2, 3
arg[two] = 2.
arg[one] = 1.
(1, 2, 3)
Python 函式 可變引數
有些時候我們可能遇到引數的個數並不固定的情況,比如1 2 3 n 函式定義如下 def calc numbers sum 0 for n in numbers sum sum n n return sum上面這種情況只能傳乙個引數,而且引數一般是list或tuple,呼叫方式 calc 1,3,5 ...
Python函式 函式的可變引數
在python函式中,還可以定義可變引數。顧名思義,可變引數就是傳入的引數個數是可變的,可以是1個 2個到任意個,還可以是0個。我們以數學題為例子,給定一組數字a,b,c 請計算a 2 b 2 c 2 我們把函式的引數改為可變引數 def calc numbers sum 0 for n in nu...
python函式的可變引數問題
deff x print x,type x f 1 f a b f 1 2,3 23,31 如上程式,定義了乙個函式,裡面的引數加 代表可變引數,也就是可以輸入多個引數,但是,輸入進去後引數的型別就發生了變化。如下為程式執行結果 1,class tuple a b class tuple 1 2,3...