Python編程:定義函數(shù)輸入?yún)?shù)很簡單?這些規(guī)則掌握了沒_第1頁
Python編程:定義函數(shù)輸入?yún)?shù)很簡單?這些規(guī)則掌握了沒_第2頁
Python編程:定義函數(shù)輸入?yún)?shù)很簡單?這些規(guī)則掌握了沒_第3頁
Python編程:定義函數(shù)輸入?yún)?shù)很簡單?這些規(guī)則掌握了沒_第4頁
Python編程:定義函數(shù)輸入?yún)?shù)很簡單?這些規(guī)則掌握了沒_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第Python編程:定義函數(shù)輸入?yún)?shù)很簡單?這些規(guī)則掌握了沒?位置或關(guān)鍵字參數(shù):同時允許位置和關(guān)鍵字參數(shù);

可變位置參數(shù):在元組中收集任意數(shù)量的位置參數(shù);

可變關(guān)鍵字參數(shù):在字典中收集任意數(shù)量的關(guān)鍵字參數(shù);

僅限位置參數(shù):只能作為位置參數(shù)傳遞;

僅限關(guān)鍵字參數(shù):只能作為關(guān)鍵字參數(shù)傳遞。

到目前為止,我們所看到的例子中,看到的所有參數(shù)都是普通的位置參數(shù)或關(guān)鍵字參數(shù)。也已經(jīng)了解了如何將它們作為位置參數(shù)和關(guān)鍵字參數(shù)傳遞。關(guān)于它們沒有太多要說的了,所以我們要來看看其他類別。在此之前,先來看看可選參數(shù)。

1.可選參數(shù)

除了我們在這里看到的類別之外,參數(shù)還可以分為必選項(xiàng)和可選項(xiàng)。可選參數(shù)有默認(rèn)值,其值在函數(shù)定義中指定。語法是格式為:name=value。示例如下:

#定義參數(shù)有默認(rèn)值的函數(shù),調(diào)用時其為可選型參數(shù)

deffunc(a,b=4,c=88):

print(a,b,c)

func(1)#prints:1488

func(b=5,a=7,c=9)#prints:759

func(42,c=9)#prints:4249

func(42,43,44)#prints:42,43,44

這里,a是必需傳遞參數(shù)項(xiàng),而b的默認(rèn)值是4,c的默認(rèn)值是88,兩者是可選項(xiàng)。重要的是要注意,除了只有關(guān)鍵字的形參外,必需型形參必須始終位于函數(shù)定義中所有可選形參的左側(cè)。試著在上面的例子中刪除c的默認(rèn)值,看看會發(fā)生什么。

2.不定量位置參數(shù)

有時,可能不希望為函數(shù)指定位置參數(shù)的確切數(shù)量,而Python通過使用可變位置參數(shù)提供了實(shí)現(xiàn)這一點(diǎn)的能力。讓我們來看一個非常常見的用例,minimum()函數(shù)。

這是一個計(jì)算其輸入值最小值的函數(shù),代碼如下:

#不定量位置參數(shù)

defminimum(*n):

#print(type(n))#n是個元組

ifn:#

mn=n[0]

forvalueinn[1:]:

ifvaluemn:

mn=value

print(mn)

minimum(1,3,-7,9)#n=(1,3,-7,9)-prints:-7

minimum()#n=()-prints:nothing

如上所見,當(dāng)我們定義一個帶有星號*的形參時,我們是在告訴Python,當(dāng)函數(shù)被調(diào)用時,這個形參將收集數(shù)量不定的位置實(shí)參。在函數(shù)中,n是一個元組??扇∠a中的注釋print(type(n))行,然后運(yùn)行程序并看看輸出。

注意,一個函數(shù)最多只能有一個不定量位置參數(shù)有更多的位置參數(shù)是沒有意義的。Python將無法決定如何劃分它們之間的參數(shù)。您也無法為變量位置參數(shù)指定默認(rèn)值。默認(rèn)值總是一個空元組。

提示:

是否注意到代碼中是如何用一個簡單的ifn:檢查n是否為空的這是因?yàn)樵赑ython中,集合對象在非空時求值為True,否則為False。元組、集合、列表、字典等等都是如此。

另一件需要注意的事情是,當(dāng)調(diào)用不帶參數(shù)的函數(shù)時,可能想拋出一個錯誤,而不是靜默地什么都不做。在這種情況下,我們不關(guān)心如何使這個函數(shù)健壯,而是要理解可變量位置參數(shù)。

另外,是否注意到,定義不定量位置形參的語法與可迭代解包的語法非常相似這并非巧合。畢竟,這兩個特征互為鏡像。它們也經(jīng)常一起使用,因?yàn)椴欢课恢眯螀⒆屇悴槐負(fù)?dān)心解包的可迭代對象的長度是否與函數(shù)定義中的形參數(shù)量相匹配。

3.不定量關(guān)鍵字參數(shù)

不定量關(guān)鍵字參數(shù)(Variablekeywordparameters)非常類似于不定量位置參數(shù)。唯一的區(qū)別是語法(**而不是*)和它們以字典形式被收集的事實(shí):

#不定量關(guān)鍵字參數(shù)

deffunc(**kwargs):

print(kwargs)

func(a=1,b=42)#prints{a:1,b:42}

func()#prints{}

func(a=1,b=46,c=99)#prints{a:1,b:46,c:99}

如上所示,在函數(shù)定義的參數(shù)名稱前添加**告訴Python使用該名稱來收集數(shù)量不定的關(guān)鍵字參數(shù)。與不定量位置參數(shù)的情況一樣,每個函數(shù)最多只能有一個可變關(guān)鍵字參數(shù),并且不能指定默認(rèn)值。

就像可變量位置參數(shù)類似于可迭代解包一樣,可變關(guān)鍵字參數(shù)類似于字典解包。字典解包也經(jīng)常用于將參數(shù)傳遞給具有可變量關(guān)鍵字形參的函數(shù)。

為什么能夠傳遞可變數(shù)量的關(guān)鍵字參數(shù)如此重要,目前可能還不清楚,那么通過如何使用這一能力的示例,你將能更真實(shí)的理解其重要性。

我們定義一個連接到數(shù)據(jù)庫的函數(shù):我們希望通過不帶參數(shù)地調(diào)用這個函數(shù)來連接到默認(rèn)數(shù)據(jù)庫。還希望通過向函數(shù)傳遞適當(dāng)?shù)膮?shù)來連接到任何其他數(shù)據(jù)庫。在你繼續(xù)讀下去之前,自己試著花幾分鐘自己想出一個解決方案:

#可變量關(guān)鍵字參數(shù)

defconnect(**options):

conn_params={

host:options.get(host,),

port:options.get(port,5432),

user:options.get(user,),

pwd:options.get(pwd,),

print(conn_params)

#然后連接數(shù)據(jù)庫(注釋掉的代碼行)

#db.connect(**conn_params)

connect()

connect(host=2,port=5433)

connect(port=5431,user=admin,pwd=super)

注意,在函數(shù)中,我們可以準(zhǔn)備一個連接參數(shù)字典(conn_params)使用默認(rèn)值作為回退,其允許在函數(shù)調(diào)用時提供以覆蓋它們。有更好的方法可以用更少的代碼行來實(shí)現(xiàn)這一點(diǎn),但我們現(xiàn)在不關(guān)心這一點(diǎn)。運(yùn)行上述代碼會得到以下結(jié)果:

{a:1,b:46,c:99}

{host:,port:5432,user:,pwd:}

{host:2,port:5433,user:,pwd:}

{host:,port:5431,user:admin,pwd:super}

注意函數(shù)調(diào)用和輸出之間的對應(yīng)關(guān)系,以及如何根據(jù)傳遞給函數(shù)的內(nèi)容重寫默認(rèn)值。

4.僅限位置參數(shù)

從Python3.8開始,PEP570(/dev/peps/pep-0570/)引入了僅限位置的參數(shù)。有一種新的函數(shù)參數(shù)語法,/,表示一組函數(shù)形參必須在位置上指定,不能作為關(guān)鍵字參數(shù)傳遞。讓我們看一個簡單的例子:

#僅限位置參數(shù)

deffunc(a,b,/,c):

print(a,b,c)

func(1,2,3)#prints:123

func(1,2,c=3)#prints123

在上面的例子中,我們定義了一個函數(shù)func(),它指定了三個參數(shù):a、b和c。函數(shù)簽名中的/表示a和b必須按位置傳遞,也就是說,不能通過關(guān)鍵字傳遞。

示例中的最后兩行顯示,我們可以按位置傳遞所有三個參數(shù)來調(diào)用函數(shù),或者可以按關(guān)鍵字傳遞c。這兩種情況都可以正常工作,因?yàn)閏定義在函數(shù)簽名中的/之后。如果我們試圖通過通過關(guān)鍵字傳遞a或b來調(diào)用函數(shù),像這樣:

func(1,b=2,c=3)

這將產(chǎn)生如下類似回溯跟蹤信息:

Traceback(mostrecentcalllast):

File,line9,in

func(1,b=2,c=3)

TypeError:func()gotsomepositional-onlyargumentspassedaskeywordarguments:b

前面的例子告訴我們,Python現(xiàn)在反饋給我們調(diào)用func()的方式,其意思是:通過關(guān)鍵字傳遞了參數(shù)b,但不允許這樣做。

僅限位置參數(shù)也可以是可選的,如下所示:

#可選的僅限位置參數(shù)

deffunc(a,b=2,/):

print(a,b)

func(4,5)#prints45

func(3)#prints32

通過一些從官方文檔中借來的例子來看看這個特性給該語言帶來了什么。一個優(yōu)點(diǎn)是能夠完全模擬現(xiàn)有C編碼函數(shù)的行為:

defdivmod(a,b,/):

模擬內(nèi)建函數(shù)divmod()

return(a//b,a%b)

另一個重要的用例是在形參名沒有啥有意義的幫助的情況下排除關(guān)鍵字實(shí)參:

len(obj=hello)

在上面的例子中,obj關(guān)鍵字參數(shù)降低了可讀性。此外,如果我們希望重構(gòu)len函數(shù)的內(nèi)部結(jié)構(gòu),并將obj重命名為the_object(或任何其他名稱),更改保證不會破壞任何客戶端代碼,因?yàn)椴粫腥魏螌en()函數(shù)的調(diào)用,會涉及到現(xiàn)在已經(jīng)過時的obj參數(shù)名稱。

最后,使用僅限位置形參意味著/左邊的任何值都可以在不定量關(guān)鍵字實(shí)參中使用,如下例所示:

deffunc_name(name,/,**kwargs):

print(name)

print(kwargs)

func_name(Positional-onlyname,name=Namein**kwargs)

#打印輸出為:

#Positional-onlyname

#{name:Namein**kwargs}

在函數(shù)簽名中保留參數(shù)名以便在**kwargs中使用的能力可以生成更簡單、更清晰的代碼。

現(xiàn)在來研究一下僅限位置類似版:僅限關(guān)鍵字參數(shù)。

5.僅限關(guān)鍵字參數(shù)

Python3引入了僅限關(guān)鍵字的參數(shù)。我們只簡要地研究它們,因?yàn)樗鼈兊挠美⒉怀R?。有兩種方法可以指定它們,要么在不定量位置參數(shù)之后,要么在不定的*之后。來看兩個例子。代碼如下:

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

defkwo(*a,c):

print(a,c)

kwo(1,2,3,c=7)#prints:(1,2,3)7

kwo(c=4)#prints:()4

#kwo(1,2)#此行出問題無效于法,并有如下錯誤

#TypeError:kwo()missing1requiredkeyword-onlyargument:c

defkwo2(a,b=42,*,c):

print(a,b,c)

kwo2(3,b=7,c=99)#prints:3799

kwo2(3,c=13)#prints:34213

#kwo2(3,23)#此行出問題無效于法,并有如下錯誤

#TypeError:kwo2()missing1requiredkeyword-onlyargument:c

正如預(yù)期的那樣,函數(shù)kwo()接受數(shù)量可變的位置參數(shù)(a)和一個只有關(guān)鍵字的關(guān)鍵字c。調(diào)用的結(jié)果很簡單,你可以取消對第三個調(diào)用的注釋,以查看Python返回什么錯誤。

同樣的情況也適用于函數(shù)kwo2(),它與kwo的不同之處在于,它接受一個位置參數(shù)a、一個關(guān)鍵字參數(shù)b和一個只有關(guān)鍵字的參數(shù)c。你可以取消對第三個調(diào)用的注釋,以查看產(chǎn)生的錯誤。

現(xiàn)在應(yīng)已知道了如何指定不同類型的輸入?yún)?shù),接下來看看如何在函數(shù)定義中組合它們。

6.組合輸入?yún)?shù)

可以在同一個函數(shù)中組合不同的參數(shù)類型(事實(shí)上,這樣做通常非常有用)。就像在同一個函數(shù)調(diào)用中組合不同類型的實(shí)參一樣,在順序上有一些限制:

僅限位置的參數(shù)放在前面,然后跟隨一個斜杠/。

普通參數(shù)在任何僅限位置參數(shù)之后。

不定量位置參數(shù)在正常參數(shù)之后。

只有關(guān)鍵字參數(shù)在不定量位置參數(shù)之后。

不定量關(guān)鍵字參數(shù)總是排在最后。

對于僅限位置參數(shù)和普通參數(shù),任何必需的參數(shù)必須在任何可選參數(shù)之前定義。這意味著,如果你有一個可選的僅限位置參數(shù),那么所有常規(guī)參數(shù)也必須是可選的。該規(guī)則不影響僅限關(guān)鍵字的參數(shù)。

如果沒有例子,這些規(guī)則可能會有點(diǎn)難以理解,所以來看幾個示例:

#定義個帶有所有參數(shù)形式的函數(shù)

deffunc(a,b,c=7,*args,**kwargs):

print(a,b,c:,a,b,c)

print(args:,args)

print(kwargs:,kwargs)

func(1,2,3,5,7,9,A=a,B=b)

注意函數(shù)定義中參數(shù)的順序。執(zhí)行該程序會得到以下結(jié)果:

a,b,c:123

args:(5,7,9)

kwargs:{A:a,B:b}

現(xiàn)在再來看一個只有關(guān)鍵字參數(shù)的例子:

#僅限觀自在參數(shù)

defallparams(a,/,b,c=42,*args,d=256,e,**kwargs):

print(a,b,c:,a,b,c)

print(d,e:,d,e)

print(args:,args)

print(kwargs:,kwargs)

allparams(1,2,3,4,5,6,e=7,f=9,g=10)

注意,在函數(shù)聲明中有僅限位置形參和僅限關(guān)鍵字形參:a僅限位置形參,而d和e僅限關(guān)鍵字形參。他們是在*args可變量位置參數(shù)之后,如果它們緊跟在單個*的后面,也會是一樣的(在這種情況下,將沒有任何可變位置參數(shù))。運(yùn)行程序會得到以下結(jié)果:

a,b,c:123

d,e:2567

args:(4,5,6)

kwargs:{f:9,g:10}

另一件需要注意的事情是我們?yōu)榭勺兞课恢脜?shù)和關(guān)鍵字參數(shù)命名。你可以自由選擇不同的名稱,但請注意,args和kwargs是這些參數(shù)的常規(guī)名稱,至少在一般情況下是這樣。

7.更多的簽名示例

為了簡要回顧一下使用僅限位置和關(guān)鍵字說明符的函數(shù)簽名,下面是一些進(jìn)一步的示例。省略不定量位置和關(guān)鍵字參數(shù),為簡潔起見,我們只剩下以下語法:

defxxxFuncName(positional_only_parameters,/,

positional_or_keyword_parameters,*,

keyword_only_parameters):

#函數(shù)體

pass

首先,我們有僅限位置的參數(shù),然后是位置或關(guān)鍵字參數(shù),最后是僅限關(guān)鍵字參數(shù)。

其他一些有效簽名如下:

defxxxFuncName(p1,p2,/,p_or_kw,*,kw):

defxxxFuncName(p1,p2=None,/,p_or_kw=None,*,kw):

defxxxFuncName(p1,p2=None,/,*,kw):

defxxxFuncName(p1,p2=None,/):

defxxxFuncName(p1,p2,/,p_or_kw):

defxxxFuncName(p1,p2,/):

以上均為有效簽名,下列為無效簽名:

defxxxFuncName(p1,p2=None,/,p_or_kw,*,kw):

defxxxFuncName(p1=None,p2,/,p_or_kw=None,*,kw):

defxxxFuncName(p1=None,p2,/):

你可以在官方文檔中閱讀語法規(guī)范:

/3/reference/compound_stmts.html#functiondefinitions

提示:在這一點(diǎn)上,要很好的理解與掌握,一個有用的練習(xí)方法是實(shí)現(xiàn)上述示例簽名中的任何一個,打印出這些參數(shù)的值,就像我們在前面的練習(xí)中所做的那樣,并以不同的方式傳遞參數(shù)。

8.避免陷阱!可變默認(rèn)值

要注意的一件事是,在Python中,默認(rèn)值是在定義時創(chuàng)建的;因此,根據(jù)默認(rèn)值的可變性,對同一函數(shù)的后續(xù)調(diào)用可能會有不同的行為。讓我們看一個例子:

#帶有可變默認(rèn)值參數(shù)函數(shù)

deffunc(a=[],b={}):

print(a)

print(b)

print(#*12)

a.append(len(a))#影響a的默認(rèn)值

b[len(a)]=len(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論