官术网_书友最值得收藏!

3.5 函數(shù)

提到函數(shù),大家首先會想到數(shù)學(xué)函數(shù)。數(shù)學(xué)中,函數(shù)是非常重要的知識點,貫穿整個數(shù)學(xué)的學(xué)習(xí)過程。Python中,函數(shù)的應(yīng)用同樣非常廣泛,地位也非常重要。

前面我們已經(jīng)多次接觸過函數(shù),如用于輸出的print()函數(shù)、用于輸入的input()函數(shù),以及用于生成一系列整數(shù)的range()函數(shù)等。這些都是Python內(nèi)置的標(biāo)準(zhǔn)函數(shù),可以直接使用。除了這些標(biāo)準(zhǔn)庫函數(shù)外,Python還支持用戶自定義函數(shù),即用戶可將一段有規(guī)律、重復(fù)的代碼定義為函數(shù),實現(xiàn)一次編寫、多次調(diào)用的目的。使用函數(shù)可以提高代碼的重復(fù)利用率。

3.5.1 函數(shù)的定義

創(chuàng)建函數(shù)的過程就是定義函數(shù)的過程,Python中使用def關(guān)鍵字來實現(xiàn)。具體的語法格式如下:

def functionname([parameterlist]):
   ['''comments''']
   [functionbody]

參數(shù)說明:

 functionname:函數(shù)名稱,在調(diào)用函數(shù)時使用。

 parameterlist:可選參數(shù),用于指定向函數(shù)中傳遞的參數(shù)。如果有多個參數(shù),各參數(shù)間使用逗號“,”分隔。如果不指定,表示該函數(shù)沒有參數(shù),調(diào)用時同樣不用指定參數(shù)。

 '''comments''':可選參數(shù),表示為函數(shù)指定注釋,注釋的內(nèi)容通常是說明該函數(shù)的功能、要傳遞的參數(shù)的作用等,可以為用戶提供友好提示和幫助的內(nèi)容。

 functionbody:可選參數(shù),用于指定函數(shù)體,即該函數(shù)被調(diào)用后要執(zhí)行的功能代碼。如果函數(shù)有返回值,可以使用return語句返回。

注意

① 即使函數(shù)沒有參數(shù),也必須保留一對空的小括號“()”,否則將提示如圖3.47所示的錯誤。

② 函數(shù)體“functionbody”和注釋'''comments'''相對于def關(guān)鍵字,必須保持一定的縮進。

圖3.47 語法錯誤對話框

說明

定義函數(shù)時如果指定了'''comments'''參數(shù),調(diào)用函數(shù)時輸入函數(shù)名稱及左側(cè)的小括號,將顯示該函數(shù)的幫助信息,如圖3.48所示。這些幫助信息是通過定義的注釋提供的。如果沒有顯示友好提示,需要檢查函數(shù)是否有誤,檢查方法如下:調(diào)用該方法前,先按F5鍵執(zhí)行一遍代碼。

圖3.48 調(diào)用函數(shù)時顯示友好提示

例如,定義一個過濾危險字符的函數(shù)filterchar(),代碼如下:

運行上面的代碼,將不顯示任何內(nèi)容,也不會拋出異常,因為filterchar()函數(shù)還沒有被調(diào)用。

說明

如果想定義一個什么也不做的空函數(shù),可以使用pass語句作為占位符。

3.5.2 函數(shù)的調(diào)用

調(diào)用函數(shù)的過程就是執(zhí)行函數(shù)的過程。如果把創(chuàng)建函數(shù)理解為創(chuàng)建一個具有某種用途的工具,那么調(diào)用函數(shù)就相當(dāng)于使用該工具。調(diào)用函數(shù)的基本語法格式如下:

functionname([parametersvalue])

參數(shù)說明:

 functionname:要調(diào)用的函數(shù)名稱。必須是已經(jīng)創(chuàng)建好的函數(shù)。

 parametersvalue:可選參數(shù),用于指定各個參數(shù)的值。如果需要傳遞多個參數(shù)值,則各參數(shù)值間使用逗號“,”分隔。如果該函數(shù)沒有參數(shù),則直接寫一對小括號即可。

例如,調(diào)用在3.5.1節(jié)創(chuàng)建的filterchar()函數(shù),可以使用下面的代碼:

01  about = '我是一名程序員,喜歡看黑客方面的圖書,想研究一下Trojan。'
02  filterchar(about)

調(diào)用filterchar()函數(shù)后,將顯示如圖3.49所示的結(jié)果。

圖3.49 調(diào)用filterchar()函數(shù)的結(jié)果

3.5.3 函數(shù)參數(shù)的傳遞

調(diào)用函數(shù)時,多數(shù)情況下主調(diào)函數(shù)和被調(diào)函數(shù)之間存在一定的數(shù)據(jù)傳遞關(guān)系,這種數(shù)據(jù)傳遞是通過函數(shù)參數(shù)來實現(xiàn)的。函數(shù)參數(shù)包括形式參數(shù)和實際參數(shù)兩種,下面來詳細講解。

1.形式參數(shù)和實際參數(shù)

定義函數(shù)時,函數(shù)名后面括號中的參數(shù)稱為形式參數(shù),簡稱形參。

如圖3.50所示,這里person、height和weight是fun_bmi()函數(shù)的3個形參,這里并沒有給出具體的數(shù)值,而只是簡單對參數(shù)數(shù)量、含義進行了說明。

圖3.50 函數(shù)形參

調(diào)用函數(shù)時,函數(shù)名后面括號中的參數(shù)稱為實際參數(shù),簡稱實參。簡而言之,實參就是函數(shù)調(diào)用者提供給函數(shù)參與實際運算的參數(shù),有著具體的值或意義。例如,函數(shù)調(diào)用語句“fun_bmi("路人甲",1.83, 60)”中,“路人甲”、1.83和60就是給出的3個需要參與實際運算的參數(shù),這就是實參。

形參和實參的關(guān)系可以通過圖3.51更好地理解。

圖3.51 形式參數(shù)與實際參數(shù)

【實例3.18】 輸出某個人的BMI指數(shù)。(實例位置:資源包\Code\03\18)

在IDLE中創(chuàng)建function_bmi.py文件,然后在該文件中創(chuàng)建一個名稱為function_tips的函數(shù),該函數(shù)包含3個參數(shù),分別用于指定姓名、身高和體重,再根據(jù)公式“BMI =體重/ (身高×身高)”,計算人的BMI指數(shù),并輸出計算結(jié)果。

具體代碼如下:

運行結(jié)果如圖3.52所示。

從該實例代碼和運行結(jié)果可以看出:

(1)定義一個根據(jù)身高、體重計算BMI指數(shù)的函數(shù)fun_bmi(),在定義函數(shù)時指定的變量person、height和weight稱為形式參數(shù)。

(2)在函數(shù)fun_bmi()中根據(jù)形式參數(shù)的值計算BMI指數(shù),并輸出相應(yīng)的信息。

(3)調(diào)用fun_bmi()函數(shù)時,指定的“路人甲”、1.83和60都是實際參數(shù),函數(shù)執(zhí)行時這些值將被傳遞給對應(yīng)的形式參數(shù)。

圖3.52 調(diào)用函數(shù)輸出勵志文字

2.值傳遞和引用傳遞

函數(shù)調(diào)用時,實參將傳遞數(shù)據(jù)給形參,傳遞的可能是實參的值,也可能是實參的引用。具體來說,當(dāng)實參為不可變對象時,進行的是值傳遞;當(dāng)實參為可變對象時,進行的是引用傳遞。

值傳遞和引用傳遞的基本區(qū)別在于:進行值傳遞后,改變形參的值,實參的值不受影響;進行引用傳遞后,改變形參的值,實參的值也將一同被改變。

例如,定義一個名稱為demo的函數(shù),然后為demo()函數(shù)傳遞一個字符串類型的變量作為參數(shù)(代表值傳遞),并在函數(shù)調(diào)用前后分別輸出該字符串變量;再為demo()函數(shù)傳遞一個列表類型的變量作為參數(shù)(代表引用傳遞),并在函數(shù)調(diào)用前后分別輸出該列表。代碼如下:

上面代碼的執(zhí)行結(jié)果如下:

從運行結(jié)果可以看出,進行值傳遞時,改變形參的值后,實參的值未發(fā)生改變;進行引用傳遞時,改變形參的值后,實參的值也發(fā)生了改變。

3.位置參數(shù)

在函數(shù)定義(或調(diào)用)階段,按照從左到右的順序定義(或調(diào)用)的參數(shù),稱為位置參數(shù)。位置參數(shù)又稱為必備參數(shù),凡是按位置定義的形參都必須被傳值,多一個不行,少一個也不行,否則將產(chǎn)生錯誤。

1)數(shù)量必須與定義時一致

調(diào)用函數(shù)時,指定的實參數(shù)量必須與形參數(shù)量一致,否則將拋出TypeError異常,提示缺少必要的位置參數(shù)。例如,調(diào)用實例3.18中編寫的BMI指數(shù)函數(shù)fun_bmi(person,height,weight),將參數(shù)少傳一個,即只傳遞兩個參數(shù),代碼如下:

fun_bmi("路人甲",1.83)            #計算路人甲的BMI指數(shù)

函數(shù)調(diào)用后,將顯示如圖3.53的錯誤提示。拋出的異常類型為TypeError,具體提示信息為“fun_bmi()方法缺少一個必要的位置參數(shù)weight”。

2)位置必須與定義時一致

在調(diào)用函數(shù)時,指定的實參位置必須與形參位置一致,否則將拋出TypeError異常或得到錯誤結(jié)果。

圖3.53 缺少必要的參數(shù)時拋出的異常

(1)拋出TypeError異常。調(diào)用函數(shù)時,當(dāng)實參類型與形參類型不一致,且兩種類型間無法自動轉(zhuǎn)換時,將拋出TypeError異常。例如,調(diào)用實例3.18中編寫的fun_bmi(person,height,weight)函數(shù),將第1個參數(shù)和第2個參數(shù)位置調(diào)換,代碼如下:

fun_bmi(60,"路人甲",1.83)            #計算路人甲的BMI指數(shù)

函數(shù)調(diào)用后,將顯示如圖3.54所示的異常信息。這是因為傳遞的整型數(shù)值不能與字符串進行連接操作。

圖3.54 提示不支持的操作數(shù)類型

(2)產(chǎn)生的結(jié)果與預(yù)期不符。調(diào)用函數(shù)時,如果實參與形參位置不一致,但數(shù)據(jù)類型一致,則不會拋出異常,而是產(chǎn)生與預(yù)期不符的結(jié)果。例如,仍然調(diào)用fun_bmi(person,height,weight)函數(shù),將第2個參數(shù)和第3個參數(shù)位置調(diào)換,代碼如下:

fun_bmi("路人甲",60,1.83)           #計算路人甲的BMI指數(shù)

函數(shù)調(diào)用后,結(jié)果如圖3.55所示。這里雖然未拋出異常,但得到的結(jié)果并不是我們想要的。

圖3.55 結(jié)果與預(yù)期不符

說明

當(dāng)傳遞的實參位置與形參位置不一致時,并不總會拋出異常,所以在調(diào)用函數(shù)時一定要確定好位置,否則容易產(chǎn)生Bug,而且很不容易發(fā)現(xiàn)。

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

關(guān)鍵字參數(shù)是指使用形參的名字來確定輸入的參數(shù)值。通過該方式指定實參時,不再需要與形參的位置完全一致。只要將參數(shù)名寫正確即可。這樣可以避免用戶需要牢記參數(shù)位置的麻煩,使得函數(shù)的調(diào)用和參數(shù)傳遞更加靈活方便。

例如,調(diào)用fun_bmi(person,height,weight)函數(shù)時,通過關(guān)鍵字參數(shù)指定各個實際參數(shù),代碼如下:

fun_bmi( height = 1.83, weight = 60, person = "路人甲")  #計算路人甲的BMI指數(shù)

函數(shù)調(diào)用后,將顯示以下結(jié)果:

路人甲的身高:1.83米 體重:60千克
路人甲的BMI指數(shù)為:17.916330735465376
您的體重過輕 ~@_@~

從結(jié)果可以看出,雖然指定的實參順序與函數(shù)定義中不一致,但運行結(jié)果與預(yù)期是一致的。

主站蜘蛛池模板: 永和县| 澄城县| 台北市| 沅江市| 虞城县| 新沂市| 潼关县| 淮南市| 承德县| 宜黄县| 台东市| 乳源| 东乡县| 新宾| 舞阳县| 连南| 怀来县| 巩留县| 翁源县| 木兰县| 望谟县| 民丰县| 镇赉县| 怀远县| 长治县| 通河县| 安乡县| 望城县| 江北区| 万全县| 龙陵县| 黄平县| 伽师县| 甘肃省| 绥江县| 三门县| 宁津县| 石城县| 额济纳旗| 沭阳县| 垣曲县|