python 與 引數問題

2021-09-28 11:51:03 字數 4612 閱讀 7907

可變引數

在python函式中,還可以定義可變引數。顧名思義,可變引數就是傳入的引數個數是可變的,可以是1個、2個到任意個,還可以是0個。

我們以數學題為例子,給定一組數字a,b,c……,請計算a2 + b2 + c2 + ……。

要定義出這個函式,我們必須確定輸入的引數。由於引數個數不確定,我們首先想到可以把a,b,c……作為乙個list或tuple傳進來,這樣,函式可以定義如下:

def

calc

(numbers)

:sum=0

for n in numbers:

sum=

sum+ n * n

return

sum

但是呼叫的時候,需要先組裝出乙個list或tuple:

'''

'''>>

> calc([1

,2,3

])14>>

> calc((1

,3,5

,7))

84

如果利用可變引數,呼叫函式的方式可以簡化成這樣:

>>

> calc(1,

2,3)

14>>

> calc(1,

3,5,

7)84

所以,我們把函式的引數改為可變引數:

'''

'''def

calc

(*numbers)

:sum=0

for n in numbers:

sum=

sum+ n * n

return

sum

定義可變引數和定義list或tuple引數相比,僅僅在引數前面加了乙個*號。在函式內部,引數numbers接收到的是乙個tuple,因此,函式**完全不變。但是,呼叫該函式時,可以傳入任意個引數,包括0個引數:

'''

'''>>

> calc(1,

2)5>>

> calc(

)0

如果已經有乙個list或者tuple,要呼叫乙個可變引數怎麼辦?可以這樣做:

>>

> nums =[1

,2,3

]>>

> calc(nums[0]

, nums[1]

, nums[2]

)14

這種寫法當然是可行的,問題是太繁瑣,所以python允許你在list或tuple前面加乙個*號,把list或tuple的元素變成可變引數傳進去:

'''

'''>>

> nums =[1

,2,3

]>>

> calc(

*nums)

14

這種寫法相當有用,而且很常見。

關鍵字引數

可變引數允許你傳入0個或任意個引數,這些可變引數在函式呼叫時自動組裝為乙個tuple。而關鍵字引數允許你傳入0個或任意個含引數名的引數,這些關鍵字引數在函式內部自動組裝為乙個dict。請看示例:

def

person

(name, age,

**kw)

:print

'name:'

, name,

'age:'

, age,

'other:'

, kw

函式person除了必選引數name和age外,還接受關鍵字引數kw。在呼叫該函式時,可以只傳入必選引數:

'''

'''>>

> person(

'michael',30

)name: michael age:

30 other:

也可以傳入任意個數的關鍵字引數:

>>

> person(

'bob',35

, city=

'beijing'

)name: bob age:

35 other:

>>

> person(

'adam',45

, gender=

'm', job=

'engineer'

)name: adam age:

45 other:

關鍵字引數有什麼用?它可以擴充套件函式的功能。比如,在person函式裡,我們保證能接收到name和age這兩個引數,但是,如果呼叫者願意提供更多的引數,我們也能收到。試想你正在做乙個使用者註冊的功能,除了使用者名稱和年齡是必填項外,其他都是可選項,利用關鍵字引數來定義這個函式就能滿足註冊的需求。

和可變引數類似,也可以先組裝出乙個dict,然後,把該dict轉換為關鍵字引數傳進去:

'''

'''>>

> kw =

>>

> person(

'jack',24

, city=kw[

'city'

], job=kw[

'job'])

name: jack age:

24 other:

當然,上面複雜的呼叫可以用簡化的寫法:

>>

> kw =

>>

> person(

'jack',24

,**kw)

name: jack age:

24 other:

引數組合

在python中定義函式,可以用必選引數、預設引數、可變引數和關鍵字引數,這4種引數都可以一起使用,或者只用其中某些,但是請注意,引數定義的順序必須是:必選引數、預設引數、可變引數和關鍵字引數。

比如定義乙個函式,包含上述4種引數:

def

func

(a, b, c=0,

*args,

**kw)

:print

'a ='

, a,

'b ='

, b,

'c ='

, c,

'args ='

, args,

'kw ='

, kw

在函式呼叫的時候,python直譯器自動按照引數位置和引數名把對應的引數傳進去。

'''

'''>>

> func(1,

2)a =1 b =

2 c =

0 args =

() kw =

>>

> func(1,

2, c=3)

a =1 b =

2 c =

3 args =

() kw =

>>

> func(1,

2,3,

'a',

'b')

a =1 b =

2 c =

3 args =

('a'

,'b'

) kw =

>>

> func(1,

2,3,

'a',

'b', x=99)

a =1 b =

2 c =

3 args =

('a'

,'b'

) kw =

最神奇的是通過乙個tuple和dict,你也可以呼叫該函式:

>>

> args =(1

,2,3

,4)>>

> kw =

>>

> func(

*args,

**kw)

a =1 b =

2 c =

3 args =(4

,) kw =

所以,對於任意函式,都可以通過類似func(*args, **kw)的形式呼叫它,無論它的引數是如何定義的。

小結

python的函式具有非常靈活的引數形態,既可以實現簡單的呼叫,又可以傳入非常複雜的引數。

預設引數一定要用不可變物件,如果是可變物件,執行會有邏輯錯誤!

要注意定義可變引數和關鍵字引數的語法:

*args是可變引數,args接收的是乙個tuple;

**kw是關鍵字引數,kw接收的是乙個dict。

以及呼叫函式時如何傳入可變引數和關鍵字引數的語法:

可變引數既可以直接傳入:func(1, 2, 3),又可以先組裝list或tuple,再通過args傳入:func((1, 2, 3));

關鍵字引數既可以直接傳入:func(a=1, b=2),又可以先組裝dict,再通過kw傳入:func()。

使用*args和**kw是python的習慣寫法,當然也可以用其他引數名,但最好使用習慣用法。

Python 與 引數問題

問題 python的函式定義中有兩種特殊的情況,即出現 的形式。如 def myfun1 username,keys 或def myfun2 username,keys 等。解釋 用來傳遞任意個無名字引數,這些引數會乙個tuple的形式訪問。用來處理傳遞任意個有名字的引數,這些引數用dict來訪問。...

Python 與 引數問題

問題 python的函式定義中有兩種特殊的情況,即出現 的形式。如 def myfun1 username,keys 或def myfun2 username,keys 等。解釋 用來傳遞任意個無名字引數,這些引數會乙個tuple的形式訪問。用來處理傳遞任意個有名字的引數,這些引數用dict來訪問。...

Python 與 引數問題

問題 python的函式定義中有兩種特殊的情況,即出現 的形式。如 def myfun1 username,keys 或def myfun2 username,keys 等。解釋 用來傳遞任意個無名字引數,這些引數會乙個tuple的形式訪問。用來處理傳遞任意個有名字的引數,這些引數用dict來訪問。...