【python】函數(shù)的位置參數(shù)/默認(rèn)參數(shù)/可變參數(shù)/關(guān)鍵字參數(shù)/命名關(guān)鍵字參數(shù)

位置參數(shù)

我們?cè)诶煤瘮?shù)計(jì)算一個(gè)數(shù)的平方時(shí),必須要給這個(gè)函數(shù)傳入一個(gè)參數(shù)——即我們要計(jì)算平方的數(shù)。

def pow(x):
    return x * x

對(duì)于函數(shù)pow來(lái)說(shuō),x就是一個(gè)位置參數(shù),當(dāng)調(diào)用這個(gè)函數(shù)時(shí),x是必須傳入有且唯一的一個(gè)參數(shù)。

當(dāng)我們想計(jì)算 x3,可以定義另一個(gè)函數(shù),那求x4呢,還要再定義嗎,其實(shí)我們只需對(duì)pow函數(shù)稍加改動(dòng)即可

def pow(x, n):
    prod = 1
    while n > 0:
        prod = prod * x
        n = n-1
    return prod

這時(shí),x 和 n 就都是位置參數(shù),在調(diào)用時(shí)必須同時(shí)傳入,按照順序依次賦值給x 和 n。

默認(rèn)參數(shù)

在實(shí)際應(yīng)用中我們必須考慮這種情況:一般求冪都是求平方,每次使用pow函數(shù)都要輸入兩個(gè)參數(shù)未免太麻煩了些,所以有了默認(rèn)參數(shù),即這個(gè)參數(shù)有個(gè)缺省值,在不輸入是默認(rèn)為缺省值。

【例1】:

def pow(x, n = 2):
    prod = 1
    while n > 0:
        prod = prod * x
        n = n-1
    return prod

當(dāng)把n由變成n=2時(shí),位置參數(shù)就變成了默認(rèn)參數(shù),當(dāng)我們只傳入一個(gè)參數(shù)時(shí),n默認(rèn)為2。即pow(3)計(jì)算的是32。

對(duì)于其他n>2的情況,就必須要傳入兩個(gè)參數(shù)了。

使用默認(rèn)參數(shù)有以下情況需要注意:

  • 函數(shù)的參數(shù)可以全由默認(rèn)參數(shù)組成

  • 但當(dāng)位置參數(shù)和默認(rèn)參數(shù)同時(shí)存在時(shí),默認(rèn)參數(shù)必須定義在位置參數(shù)的后面,否則會(huì)報(bào)錯(cuò)

  • 如何設(shè)置默認(rèn)參數(shù):
    一般把變化大的設(shè)為位置參數(shù),變化小的(默認(rèn)值使用次數(shù)占多)設(shè)為默認(rèn)參數(shù),如【例1】 的pow函數(shù)

當(dāng)有多個(gè)默認(rèn)參數(shù)時(shí),可以不按照默認(rèn)參數(shù)的定義順序給出,但必須同時(shí)給出參數(shù)名稱,如【例2】:

【例2】:

def enroll(name, gender, age = 6, city = 'Beijing', district = 'Chaoyang'):
    print('name:', name)
    print('gender:', gender)
    print('age:', age)
    print('city:', city)
    print('district:', district)

我們可以這樣調(diào)用:enroll('xiaoming', 'M', district = 'Jizhou', city = 'Tianjin')

運(yùn)行結(jié)果:

name: xiaoming
gender: M
age: 6
city: Tianjin
district: Jizhou

重點(diǎn):默認(rèn)參數(shù)必須指向不變對(duì)象

【例3】:

def add_end(L = []):
    L.append('end')
    return L

當(dāng)我們第一次運(yùn)行該函數(shù)時(shí),結(jié)果正常:

>>> add_end()
['end']

但當(dāng)我們?cè)龠\(yùn)行時(shí),會(huì)發(fā)現(xiàn):

>>> add_end()
['end', 'end']
>>> add_end()
['end', 'end', 'end']

每次運(yùn)行都會(huì)記錄這個(gè)添加的end結(jié)尾,但這并非我們的本意,究竟為何如此呢?

我們定義的默認(rèn)參數(shù)L是個(gè)變量,其指向?yàn)?[] 這個(gè)list,但運(yùn)行一次之后,其指向的list內(nèi)容發(fā)生了改變,已經(jīng)變成['end'],默認(rèn)參數(shù)的內(nèi)容就變了,不再是函數(shù)定義時(shí)的 [] 了。

所以:

定義默認(rèn)參數(shù)要牢記一點(diǎn):默認(rèn)參數(shù)必須指向不變對(duì)象!

有哪些數(shù)據(jù)類型是不變對(duì)象呢,比如:str,None,不變對(duì)象一旦創(chuàng)建,其內(nèi)部數(shù)據(jù)便不可更改,減少了由于修改數(shù)據(jù)導(dǎo)致的錯(cuò)誤。

可變參數(shù)

可變參數(shù),顧名思義,就是傳入?yún)?shù)的數(shù)量可以變化,可以是1個(gè),2個(gè),3個(gè)……

【例4】:

def cal(numbers):
    sum = 0
    for x in numbers:
        sum = sum + x
    return sum

由此我們可以計(jì)算1+2+4+5+8+...的值了,但每次調(diào)用我們傳入的numbers參數(shù)必須是一個(gè) list 或 tuple,較麻煩。此時(shí)的numbers是一個(gè)位置參數(shù),不是可變參數(shù)。

稍加改動(dòng),即可將 numbers 定義為一個(gè)可變參數(shù)

【例4.1】

def cal(*numbers):
    sum = 0
    for x in numbers:
        sum = sum + x
    return sum

只是在numbers前加了個(gè)*,numbers就成為了可變參數(shù),我們?cè)谡{(diào)用此函數(shù)時(shí)可以這樣調(diào)用:

cal(1,2,3,6,7,8),此時(shí)numbers接收到的是一個(gè)tuple,函數(shù)代碼不變,函數(shù)即可傳入任意個(gè)參數(shù),包括0個(gè)參數(shù)。

>>> cal(3,56,7,8)
74
>>> cal()
0

如果numbers是位置參數(shù)時(shí)則0個(gè)參數(shù)會(huì)報(bào)錯(cuò),因?yàn)槲恢脜?shù)是必須傳入的。

當(dāng)我已經(jīng)有一個(gè) list 或 tuple 了怎么把它傳入函數(shù)中,可以這樣做:

>>> num = [1,3,5,6,7,8]
>>> cal(*num)
30

在 list 或 tuple 前加一個(gè)*就能將其傳入函數(shù)中了。

關(guān)鍵字參數(shù)

可變參數(shù)是可以傳入任意個(gè)(包括0個(gè))參數(shù),這些可變參數(shù)在傳入時(shí)會(huì)自動(dòng)組裝成一個(gè)tuple。關(guān)鍵字參數(shù)是允許你傳入任意個(gè)(包括0個(gè))含參數(shù)名的參數(shù),這些關(guān)鍵字參數(shù)會(huì)自動(dòng)組裝成為一個(gè)dict

【例5】:

def person(name, age, **kw):
    print('name:', name, 'age:', age, kw)

函數(shù)person在調(diào)用時(shí)除了接受必選參數(shù)nameage,還接受關(guān)鍵字參數(shù)kw。調(diào)用時(shí)可以只傳入位置參數(shù)

>>> person('xiaoming','6')
name: xiaoming age: 6 {}

也可以傳入任意個(gè)數(shù)的關(guān)鍵字參數(shù):

>>> person('xiaoming','6',city = 'Beijing', job = 'Engineer')
name: xiaoming age: 6 {'city': 'Beijing', 'job': 'Engineer'}

可以看到,兩個(gè)關(guān)鍵字參數(shù)已經(jīng)自動(dòng)組成為dict了。

應(yīng)用場(chǎng)景:

在用戶注冊(cè)時(shí),用戶可以只填入姓名,年齡兩個(gè)參數(shù),但提供城市,職業(yè)等參數(shù)選填。

與可變參數(shù)相同,我們也可以提前組裝好一個(gè)dict,之后利用**dict名將其傳入函數(shù):

>>> d = { 'city' : 'Beijing', 'job' : 'Engineer'}
>>> person('xiaoming', 6, **d)
name: xiaoming age: 6 {'city': 'Beijing', 'job': 'Engineer'}

**d會(huì)將此dict的所有key-value用關(guān)鍵字參數(shù)傳入到函數(shù)的**kw參數(shù)中,kw將獲得一個(gè)dict,其獲得的是d的一份拷貝,對(duì)**kw做任何改動(dòng)不會(huì)影響d

命名關(guān)鍵字參數(shù)

關(guān)鍵字參數(shù)允許我們傳入任意個(gè)含參數(shù)名的關(guān)鍵字參數(shù),但是考慮到限制用戶輸入的隨意性,如何讓用戶只傳入規(guī)定的關(guān)鍵字參數(shù)呢。比如,只接受cityjob作為關(guān)鍵字參數(shù),可以這樣定義:

def person(name, age, *, city, job):
    print(name, age, city, job)

和關(guān)鍵字參數(shù)**kw不同,命名關(guān)鍵字參數(shù)只需要一個(gè)特殊分隔符*,*后面的參數(shù)都會(huì)被視為命名關(guān)鍵字參數(shù)。

調(diào)用方式如下:

>>> person('xiaoming',6,city = 'Beijing', job = 'Engineer')
xiaoming 6 Beijing Engineer

命名關(guān)鍵字參數(shù)調(diào)用時(shí)必須寫參數(shù)名,不寫的話函數(shù)會(huì)默認(rèn)將其視為位置參數(shù),將會(huì)報(bào)錯(cuò)。

如果命名關(guān)鍵字參數(shù)前面有可變參數(shù),則省略*作為分隔符,可變參數(shù)后的參數(shù)自動(dòng)視為命名關(guān)鍵字參數(shù),不必?fù)?dān)心混淆,命名關(guān)鍵字參數(shù)傳入時(shí)必須包含參數(shù)名。

def person(name, age, *args , city, job):
    print(name, age,args, city, job)
>>> person('xiaoming',6, 'This is a smart boy', 'allergic to egg', city = 'Beijing', job = 'Engineer')
xiaoming 6 ('This is a smart boy', 'allergic to egg') Beijing Engineer

命名關(guān)鍵字參數(shù)也可以有缺省值,從而簡(jiǎn)化調(diào)用:

def person(name, age, *args , city = ‘Beijing, job):
    print(name, age,args, city, job)
>>> person('xiaoming',6, 'This is a smart boy', 'allergic to egg', job = 'Engineer')
xiaoming 6 ('This is a smart boy', 'allergic to egg') Beijing Engineer

注意:

使用命名關(guān)鍵字參數(shù)時(shí),如果前面沒(méi)有可變參數(shù),必須加特殊分隔符*。如果不加,python將無(wú)法識(shí)別位置參數(shù)和命名關(guān)鍵字參數(shù)。

參數(shù)組合

這五種參數(shù)可以組合使用,但參數(shù)定義的順序必須是:

位置參數(shù)-->默認(rèn)參數(shù)-->可變參數(shù)-->命名關(guān)鍵字參數(shù)-->關(guān)鍵字參數(shù)

注意命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(shù)的順序。

比如定義一個(gè)函數(shù),包含若干上述參數(shù):

def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

可以看出,

f1包含位置參數(shù),默認(rèn)參數(shù),可變參數(shù),關(guān)鍵字參數(shù)。

f2包含位置參數(shù),默認(rèn)參數(shù),命名關(guān)鍵字參數(shù),關(guān)鍵字參數(shù)。

其中可變參數(shù)在傳入時(shí)自動(dòng)組成一個(gè)tuple,關(guān)鍵字參數(shù)傳入時(shí)自動(dòng)組成一個(gè)dict。

函數(shù)調(diào)用時(shí),python解釋器會(huì)自動(dòng)按參數(shù)位置和參數(shù)名把對(duì)應(yīng)的參數(shù)傳進(jìn)去。

f1可以只傳入位置參數(shù),f2必須傳入的有位置參數(shù),命名關(guān)鍵字參數(shù)。

>>> f1(1,2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1,2,4)
a = 1 b = 2 c = 4 args = () kw = {}
>>> f1(1,2,c=4)
a = 1 b = 2 c = 4 args = () kw = {}
>>> f1(1,2,4,'ab',2)
a = 1 b = 2 c = 4 args = ('ab', 2) kw = {}
>>> f1(1,2,4,'ab',2,city = 'Beijing')
a = 1 b = 2 c = 4 args = ('ab', 2) kw = {'city': 'Beijing'}
>>> f2(1,2,4,d = 6)
a = 1 b = 2 c = 4 d = 6 kw = {}
>>> f2(1,2,4,d = 6,city = 'Beijing')
a = 1 b = 2 c = 4 d = 6 kw = {'city': 'Beijing'}
>>> f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}

最神奇的是,通過(guò)一個(gè)tuple和dict,你也可以調(diào)用上述函數(shù):

>>> args = (1,2,3,4)
>>> kw = {'d':99,'x':'#'}
>>> f1(*args,**kw)
a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
>>> args = (1, 2, 3)
>>> kw = {'d':456,'city':'Beijing'}
>>> f2(*args,**kw)
a = 1 b = 2 c = 3 d = 456 kw = {'city': 'Beijing'}

無(wú)論函數(shù)是如何定義的,都可以通過(guò)類似func(*args,**kw)的方式調(diào)用它。

最后:

不要同時(shí)使用太多的組合,會(huì)使函數(shù)接口的可理解性很差

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文是來(lái)自廖大的python教程其中我一直忘記的部分。算是一個(gè)筆記把。因?yàn)槿粘_@倆參數(shù)名字一直搞混 可變參數(shù) 在P...
    東皇Amrzs閱讀 57,341評(píng)論 7 65
  • 1.函數(shù)參數(shù) 1.1 位置參數(shù) 我們先寫一個(gè)計(jì)算x2的函數(shù): 對(duì)于power(x)函數(shù),參數(shù)x就是一個(gè)位置參數(shù)。當(dāng)...
    時(shí)間之友閱讀 421評(píng)論 0 2
  • python函數(shù)的參數(shù)是目前見(jiàn)過(guò)最復(fù)雜的參數(shù)了。 C語(yǔ)言里用的最多的可變參數(shù)函數(shù)就是scanf和printf了,j...
    米耳閱讀 395評(píng)論 0 0
  • Python 是一種相當(dāng)高級(jí)的語(yǔ)言,通過(guò) Python 解釋器把符合語(yǔ)法的程序代碼轉(zhuǎn)換成 CPU 能夠執(zhí)行的機(jī)器碼...
    Python程序媛閱讀 2,037評(píng)論 0 3
  • 本章將介紹函數(shù)中參數(shù)的用法,更多內(nèi)容請(qǐng)參考:Python學(xué)習(xí)指南 定義函數(shù)的時(shí)候,我們把參數(shù)的名字和位置確定下來(lái),...
    小七奇奇閱讀 260評(píng)論 0 2

友情鏈接更多精彩內(nèi)容