- Python算法設(shè)計與分析從入門到精通
- 明日科技編著
- 2967字
- 2022-07-28 18:54:34
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ù)期是一致的。
- Docker and Kubernetes for Java Developers
- Xcode 7 Essentials(Second Edition)
- 趣學(xué)Python算法100例
- 從0到1:HTML+CSS快速上手
- 新手學(xué)Visual C# 2008程序設(shè)計
- Data Analysis with IBM SPSS Statistics
- PHP+MySQL網(wǎng)站開發(fā)項目式教程
- Learning Salesforce Einstein
- 快人一步:系統(tǒng)性能提高之道
- SQL Server數(shù)據(jù)庫管理與開發(fā)兵書
- Python3.5從零開始學(xué)
- Developing SSRS Reports for Dynamics AX
- Go語言開發(fā)實戰(zhàn)(慕課版)
- ActionScript 3.0從入門到精通(視頻實戰(zhàn)版)
- 零基礎(chǔ)學(xué)C++(升級版)