參數(shù)種類:5, 必選參數(shù)技即,默認(rèn)參數(shù), 可變參數(shù)樟遣,關(guān)鍵字參數(shù)而叼,命名關(guān)鍵字參數(shù)
位置參數(shù)
def power(x):
return x * x
對(duì)于power(x)函數(shù),參數(shù)x就是一個(gè)位置參數(shù)
默認(rèn)參數(shù)
- 默認(rèn)參數(shù)必須指向不變對(duì)象豹悬,可以用str葵陵、none來實(shí)現(xiàn), list是可變對(duì)象
因?yàn)椴蛔儗?duì)象一旦創(chuàng)建瞻佛,對(duì)象內(nèi)部的數(shù)據(jù)就不能修改脱篙,這樣就減少了由于修改數(shù)據(jù)導(dǎo)致的錯(cuò)誤。此外伤柄,由于對(duì)象不變绊困,多任務(wù)環(huán)境下同時(shí)讀取對(duì)象不需要加鎖,同時(shí)讀一點(diǎn)問題都沒有适刀。我們?cè)诰帉懗绦驎r(shí)秤朗,如果可以設(shè)計(jì)一個(gè)不變對(duì)象,那就盡量設(shè)計(jì)成不變對(duì)象
def add_end(L=none):
if L is none:
L=[]
L.append('end')
return L
可變參數(shù)
在Python函數(shù)中笔喉,還可以定義可變參數(shù)取视。顧名思義,可變參數(shù)就是傳入的參數(shù)個(gè)數(shù)是可變的常挚,可以是1個(gè)作谭、2個(gè)到任意個(gè),還可以是0個(gè)奄毡。
由于參數(shù)個(gè)數(shù)不確定折欠,我們首先想到可以把a(bǔ),b,c……作為一個(gè)list或tuple傳進(jìn)來
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n
return sum
calc([1,3,4])
如果利用可變參數(shù)怨酝,調(diào)用函數(shù)的方式可以簡(jiǎn)化成這樣:
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n
return sum
calc(1,2)
calc(1,3,4)
定義可變參數(shù)和定義一個(gè)list或tuple參數(shù)相比傀缩,僅僅在參數(shù)前面加了一個(gè)*
號(hào)
如果已經(jīng)有一個(gè)list或者tuple,要調(diào)用一個(gè)可變參數(shù)怎么辦农猬?
>>> nums = [1, 2, 3]
>>> calc(nums[0], nums[1], nums[2])
14
Python允許你在list或tuple前面加一個(gè)*號(hào)赡艰,把list或tuple的元素變成可變參數(shù)傳進(jìn)去
>>> nums = [1, 2, 3]
>>> calc(*nums)
14
** nums表示把nums這個(gè)list的所有元素作為可變參數(shù)傳進(jìn)去。這種寫法相當(dāng)有用斤葱,而且很常見*
可變參數(shù)允許你傳入0個(gè)或任意個(gè)參數(shù)慷垮,這些可變參數(shù)在函數(shù)調(diào)用時(shí)自動(dòng)組裝為一個(gè)tuple。而關(guān)鍵字參數(shù)允許你傳入0個(gè)或任意個(gè)含參數(shù)名的參數(shù)揍堕,這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動(dòng)組裝為一個(gè)dict
關(guān)鍵字參數(shù)
def person(name, age, **kw):
print('name:', name, ' age :', age, ' orther:' , kw )
>>> person('bob', 35, city='Beijing')
name: bob age:35, other:{'city':'Beijing'}
>>> person('bob', 35, gender='M', job='Engineer')
name: bob age:35 other:{'gender':'M', 'job': 'Engineer'}
和可變參數(shù)類似料身,也可以先組裝出一個(gè)dict,然后衩茸,把該dict轉(zhuǎn)換為關(guān)鍵字參數(shù)傳進(jìn)去
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, city=extra['city'], job=extra['job'])
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
或者簡(jiǎn)化:
>>> extra = {'city':'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
extra表示把extra這個(gè)dict的所有key-value用關(guān)鍵字參數(shù)傳入到函數(shù)的kw參數(shù)芹血,kw將獲得一個(gè)dict,注意kw獲得的dict是extra的一份拷貝楞慈,對(duì)kw的改動(dòng)不會(huì)影響到函數(shù)外的extra
命名關(guān)鍵字參數(shù)
如果要限制關(guān)鍵字參數(shù)的名字幔烛,就可以用命名關(guān)鍵字參數(shù),例如囊蓝,只接收city和job作為關(guān)鍵字參數(shù)
def person(name, age, *, city, job):
print(name, age, city, job)
和關(guān)鍵字參數(shù)kw不同饿悬,命名關(guān)鍵字參數(shù)需要一個(gè)特殊分隔符,后面的參數(shù)被視為命名關(guān)鍵字參數(shù), 調(diào)用如下:
>>>person('Jack', 24, city='Beijing', job='Engineer')
jack 24 Beijing Engineer
參數(shù)組合
在Python中定義函數(shù)聚霜,可以用必選參數(shù)狡恬、默認(rèn)參數(shù)、可變參數(shù)蝎宇、關(guān)鍵字參數(shù)和命名關(guān)鍵字參數(shù)弟劲,這5種參數(shù)都可以組合使用。但是請(qǐng)注意夫啊,參數(shù)定義的順序必須是:必選參數(shù)函卒、默認(rèn)參數(shù)辆憔、可變參數(shù)撇眯、命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(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(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
>>> f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
通過一個(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': 88, 'x': '#'}
>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}
所以熊榛,對(duì)于任意函數(shù),都可以通過類似func(*args, **kw)的形式調(diào)用它腕巡,無論它的參數(shù)是如何定義的玄坦。
小結(jié)
- Python的函數(shù)具有非常靈活的參數(shù)形態(tài),既可以實(shí)現(xiàn)簡(jiǎn)單的調(diào)用,又可以傳入非常復(fù)雜的參數(shù)煎楣。
- 默認(rèn)參數(shù)一定要用不可變對(duì)象豺总,如果是可變對(duì)象,程序運(yùn)行時(shí)會(huì)有邏輯錯(cuò)誤择懂!
- 要注意定義可變參數(shù)和關(guān)鍵字參數(shù)的語法:
- *args是可變參數(shù)喻喳,args接收的是一個(gè)tuple;
- **kw是關(guān)鍵字參數(shù)困曙,kw接收的是一個(gè)dict表伦。
以及調(diào)用函數(shù)時(shí)如何傳入可變參數(shù)和關(guān)鍵字參數(shù)的語法: - 可變參數(shù)既可以直接傳入:func(1, 2, 3),又可以先組裝list或tuple慷丽,再通過*args傳入:func(*(1, 2, 3))蹦哼;
- 關(guān)鍵字參數(shù)既可以直接傳入:func(a=1, b=2),又可以先組裝dict要糊,再通過**kw傳入:func(**{'a': 1, 'b': 2})纲熏。
- 使用*args和**kw是Python的習(xí)慣寫法,當(dāng)然也可以用其他參數(shù)名锄俄,但最好使用習(xí)慣用法赤套。
- 命名的關(guān)鍵字參數(shù)是為了限制調(diào)用者可以傳入的參數(shù)名,同時(shí)可以提供默認(rèn)值珊膜。
- 定義命名的關(guān)鍵字參數(shù)在沒有可變參數(shù)的情況下不要忘了寫分隔符*容握,否則定義的將是位置參數(shù)。