您好,登錄后才能下訂單哦!
函數(shù)的參數(shù)是參數(shù)暴露給外部的接口,向函數(shù)傳遞參數(shù),可以控制函數(shù)的流程,函數(shù)可以0個、1個或多個參數(shù);在Python中向函數(shù)傳參,使用的是賦值方式。
一,傳遞參數(shù)
參數(shù)是通過賦值來傳遞的,傳遞參數(shù)的特點是:
參數(shù)的傳遞是通過自動把對象賦值給函數(shù)的本地變量名來實現(xiàn)的,
在函數(shù)內(nèi)部的變量名的賦值不會影響調(diào)用者,在函數(shù)運行時,在函數(shù)頭部的參數(shù)名是一個新的、本地的變量名,這個變量名的作用域是在函數(shù)的本地作用域內(nèi)。
改變函數(shù)的可變對象參數(shù)的值,會修改原始對象的值。
當通過賦值方式,把可變對象的引用傳遞給函數(shù)時,在函數(shù)內(nèi)部對參數(shù)進行修改,在函數(shù)外部可以看到修改。
例如,列表是一個可變對象,當把列表 a 傳遞給 changer函數(shù)時,函數(shù)向列表末尾添加一個字符a,當函數(shù)調(diào)用結(jié)束時,列表末尾被修改。
>>> def changer(x):
... x.append('a')
...
>>> a=[1,2,3]
>>> changer(a)
>>> a
[1, 2, 3, 'a']
這是由于可變對象是通過指針進行傳遞的,當把列表的引用傳遞給參數(shù)時,函數(shù)直接在原處修改對象。
也可以通過向參數(shù)傳遞拷貝的方式,使得函數(shù)無法修改原始的對象。
changer(a[:])
changer(a.copy())
二,參數(shù)匹配模型
不管使用何種參數(shù)的匹配模型,參數(shù)總是通過賦值進行傳遞的。
在默認情況下,參數(shù)是通過其位置進行匹配的,從左向右,而且必須精確地傳遞和函數(shù)頭部參數(shù)名一樣多的參數(shù)。還能夠通過參數(shù)名匹配,默認參數(shù)名,以及對于額外參數(shù)的容器來進行傳參。
1,位置匹配
一般情況下,參數(shù)是通過位置從左至右進行匹配,把參數(shù)傳遞給函數(shù)頭部的參數(shù)名稱。
例如,定義函數(shù)func,包含三個參數(shù),那么必須使用三個參數(shù)傳值進行調(diào)用:
def func(a,b,c):
調(diào)用的格式是,按照順序把值寫在括號中,Python按照位置匹配參數(shù),把1賦值給a,把2賦值給b,把3賦值給c:
func(1,2,3)
2,關(guān)鍵字匹配
調(diào)用者使用arg_name=value的方式,通過在調(diào)用時使用參數(shù)的變量名進行匹配。
例如,定義參數(shù)func,包含三個參數(shù),那么必須使用三個參數(shù)傳值進行調(diào)用:
def func(x,y,z):
使用關(guān)鍵字調(diào)用的格式是:按照 arg=named的方式進行匹配,可以不按照位置:
func(y=2, x=1, z=3)
在調(diào)用函數(shù)時,Python按照參數(shù)名進行匹配,把2傳遞給參數(shù)y,把1傳遞給參數(shù)x,把3傳遞給參數(shù)z。
也可以混合使用位置匹配和關(guān)鍵字匹配,例如,下面的函數(shù)調(diào)用:
func(1,z=3,y=2)
基于位置的匹配參數(shù),首先按照從左至右的順序匹配前面的參數(shù),之后,再按照基于變量名進行關(guān)鍵字匹配。
3,默認參數(shù)
在定義函數(shù)時,可以為函數(shù)的參數(shù)賦值,這就是參數(shù)的默認值。當沒有為該參數(shù)傳值時,參數(shù)值使用默認值。
例如,定義一個函數(shù),包含三個參數(shù),x、y和z,其中參數(shù)z有默認值1:
def func(x,y,z=1):
當調(diào)用這個函數(shù),必須為參數(shù)x和y傳值,無論是通過位置匹配還是關(guān)鍵字匹配來實現(xiàn)都可以。然而,參數(shù)z的傳值是可選的。如果不為z傳值,那么z使用默認值;如果為z傳值,那么z使用傳遞的值。
func(2,3)
4,可變長參數(shù)列表
可變參數(shù)用于收集任意多個基于位置或關(guān)鍵字的參數(shù),在函數(shù)定義時,如果參數(shù)名前帶一個*號,那么該參數(shù)收集的是基于位置的傳值;如果參數(shù)名前帶兩個*號(**arg),那么該參數(shù)收集的是基于關(guān)鍵字(arg=value)的傳值。
def func(*args)
def func(**dict)
這兩種方式的不同點是,*args方式是把任意多個傳值封裝成元組(arg1,arg2),而**dict是把任意多個 arg=value 封裝成字典{arg:value},字典的key是參數(shù)名,字典key對應(yīng)的值是參數(shù)的值。
例如,定義函數(shù)foo,包含一個位置匹配參數(shù),1個可變的位置匹配參數(shù),1個可變的關(guān)鍵字匹配參數(shù):
def foo(a,*b,**c):
在調(diào)用函數(shù)時,首先按照位置匹配,把1傳遞給參數(shù)a,把元組(2,3)傳遞給參數(shù)b,把字典{x:1,y:2}傳遞給參數(shù)c:
foo(1,2,3,x=1,y=2)
5,只能使用關(guān)鍵字參數(shù)
參數(shù)必須按照名稱傳值,在函數(shù)定義時,參數(shù)必須在調(diào)用中按照關(guān)鍵字進行傳值:
def func(*,arg=value)
從語法上來講,keyword-only參數(shù)編碼為關(guān)鍵字參數(shù),出現(xiàn)在參數(shù)列表的*args之后,所有這些參數(shù)都必須在調(diào)用中使用關(guān)鍵字語法來傳值。
def foo(a,*b,c):
在調(diào)用foo函數(shù)時,參數(shù)a可以按照位置和關(guān)鍵字來傳值,參數(shù)b接收按照其余的按照位置來傳值的變量,參數(shù)c必須按照關(guān)鍵字來傳值:
foo(1,2,'a',3,c='key')
也可以在參數(shù)列表中使用一個*字符,來表示一個函數(shù)不會接受一個可變的參數(shù)列表,而是仍然期待跟在*后面的所有參數(shù)都作為關(guān)鍵字匹配。
例如,定義函數(shù)foo,只接受3個參數(shù),不接受可變長度的參數(shù)列表:
def foo(a,*,b,c):
在調(diào)用時,參數(shù)a可以按照位置和關(guān)鍵字來傳值,參數(shù)b和c必須按照關(guān)鍵字來傳值:
foo(1,b='x',c=2)
三,lambda表達式
除了def語句之外,Python還提供了一種生成函數(shù)對象的表達式形式,lambda表達式。就像def語句一樣,這個表達式創(chuàng)建了一個函數(shù)對象,但是它返回了一個函數(shù),而不是把這個函數(shù)賦值給一個變量名。
lambda表達式的一般形式是關(guān)鍵字lambda,之后是一個或多個參數(shù)(與一個def頭部內(nèi)用括號括起來的參數(shù)列表極其類似),緊跟一個冒號,之后是一個表達式:
lambda arg1,arg2,... argN: expression_using_args
lambda表達式的特性是:
lambda表達式返回的是函數(shù)對象;
lambda是一個表達式,而不是一個語句,作為一個表達式,lambda返回了一個值(一個新的函數(shù)),可以選擇性地賦值給一個變量名;
lambda的主體是一個單個的表達式,而不是一個代碼塊,這個表達式的結(jié)果作為函數(shù)的結(jié)果返回。
lambda只有一行表達式,只能用于創(chuàng)建簡單的函數(shù),而def 可以包含多條語句,用于處理復雜的任務(wù)。
對于簡單的處理流程,既可以使用def,也可以用lambda來實現(xiàn),例如:
def func(x,y,z): return x+y+z
func=lambda x,y,z: x+y+z
由于lambda表達式返回的是一個函數(shù)對象,因此,可以用于map()、filter()和reduce()函數(shù)中:
list(map((lambda x: x+3), range(0,5)))
list(filter((lambda x: x>2), range(0,5)))
from functools import reduce
reduce((lambda x,y: x+y),range(0,5))
reduce()函數(shù)對每對元素都應(yīng)用函數(shù),并運行到最后結(jié)果,上述reduce()函數(shù)的作用是把序列中的所有元素相加,等價的寫法是:
x=list(range(0,5)]
res=x[0]
for i in x[1:] :
res+=i
四,函數(shù)的屬性
可以向函數(shù)添加任意多個用戶定義的屬性,函數(shù)屬性的格式是:函數(shù)名稱.變量名
例如,向函數(shù)func中添加state屬性:
def func():
func.state='begin'
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。