函式是一段可重復使用的、具有特定功能的陳述句塊,通過函式名來定義和呼叫,經過定義,函式內的陳述句塊成為一個整體,即“函式體”,可以通過使用函式名的呼叫從而實作函式內部陳述句塊的重復使用,
在使用程序中,函式內部對呼叫者來說可以是完全未知的黑箱,呼叫者只要知道函式應該傳入的引數是什么、回傳的引數是什么這兩點就可以無障礙呼叫,從此方面講,函式就具有“封裝”性,
使用函式最大的優點是提高代碼的復用,并且可以進行模塊化的程式設計,同樣功能的代碼多次使用,可以大幅的節省編程成本,提高編程效率,降低代碼編程難度,同時,習慣使用函式編程,將實作不同功能的代碼寫成不同的函式,便于將編程問題和具體需求進一步細化,分而治之,
同一個程式的功能被劃分為不同的小的功能模塊,形成模塊化設計布局,不僅使得程式具有很好的可讀性,也便于程式的維護升級和兼容性提升,函式對內部封裝的特性,使得只要在定義函式的部分更改其函式體的陳述句,就能實作該功能的升級維護,整個程式中呼叫該函式的部分也會得到更新,
1.基本使用
函式的使用可以包括四個步驟,即函式定義、函式呼叫、函式執行、函式回傳,其中函式的定義部分尤為重要,其直接決定了函式應該怎么呼叫、函式的執行程序如何、函式回傳什么值等等,
Python語言通過保留字def定義函式,語法形式如下:
def <函式名>(<引數串列>):
<函式體>
return <回傳值串列>
函式名可以是任何P有效的Python識別符號,
引數串列是呼叫該函式時傳入給函式的值,可以是某個資料型別的單個引數,也可以是一個很多資料型別組成的引數串列,還可以沒有任何引數(沒有引數時,括號也不可以省略),視函式撰寫者的設計而定,引數串列以逗號分隔即可,
函式體則由具體的Python代碼塊組成,與前面學的普通Python代碼沒有任何差異,該代碼塊需要根據引數串列執行特定操作,
回傳值串列是函式傳出的引數,由return保留字建立,該串列也同引數串列一樣,可以是任何的資料型別和任意數量大小的串列,當回傳值串列的元素大小為0時,函式的執行只是對程式進行代碼塊的操作,不回傳任何值,return需要省略,
函式的呼叫,通過函式名來呼叫函式功能,對函式的各個引數賦予實際值,實際值可以是實際的資料值,也可以是在呼叫函式前已經定義過的變數,
函式的執行,是引數傳入以后,程式執行函式體功能代碼的程序,其執行程序由函式體的代碼決定,
函式回傳,函式執行完畢后,函式將回傳值串列回傳到程式,并將控制權回傳給程式,
函式定義及呼叫演示如下:
#定義回傳三個數中的最大值和最小值的函式
def compare(a,b,c):#定義函式
ma = max(a,b,c)
mi = min(a,b,c)
return ma,mi#回傳兩個值
x = 1
y = 2
z = 3
#呼叫函式compare,并將兩個回傳值依次賦值給num1,num2
num1,num2 = compare(x,y,z)
print("最大值是{0},最小值是{1}".format(num1,num2))
#輸出結果為:
最大值是3,最小值是1
函式的函式體一定需要書寫至少一行的代碼,當不希望函式做任何事時,可以使用pass保留字,保留字pass表示不進行任何操縱,起到占位的作用,演示如下:
def f():#定義空的函式
pass
f()#函式不會進行任何操作
編程中大量使用函式已經成為一種編程范式,叫做函式式編程,函式式編程的主要思想是把程式程序盡量寫成一系列函式呼叫,這樣能夠使代碼撰寫的更簡潔易讀,是中小規模軟體最常用的編程方式,
在Python中,函式也是有型別的,可以通過type()函式來獲得函式型別,函式型別是Python的內置型別,具體為function型別,當用type()檢查呼叫的函式的型別時,回傳的是函式回傳值的型別,即函式呼叫優先執行,當函式執行完畢,函式將回傳值和控制權回傳給程式,type()函式檢驗的就不再是函式,而是回傳值了,
2.引數傳遞
定義函式時引數串列中的引數,是形引數,沒有實際意義,呼叫函式時傳入的引數是實參,由出傳入的引數賦予形參意義來執行程式,
函式的引數傳遞可以分為三種情況:可選的引數傳遞、引數名稱傳遞、函式的回傳值,其中可選的引數傳遞是指,在傳入引數進函式時,可以省略掉一些引數,省略的引數用事先規定的默認值代替傳入函式,演示如下:
def compare(a,c,b=2):#使用b-2規定如果缺失b,則默認b=2
ma = max(a,b,c)
mi = min(a,b,c)
return ma,mi
x = 1
z = 3
num1,num2 = compare(x,z)#與上一例子相比省略了y
print("最大值是{0},最小值是{1}".format(num1,num2))
#輸出結果如下:
最大值是3,最小值是1
根據編程習慣,一般情況下引數串列都是先寫非可選引數,可選引數放在后面,可選引數放在前面會報錯,親測,
引數傳入函式還有另一種方法,即通過引數名稱直接賦予形參意義,使用引數名稱傳入引數給函式,對引數的順序沒有要求,演示如下:
def compare(a,c,b=2):
ma = max(a,b,c)
mi = min(a,b,c)
return ma,mi
x = 1
z = 3
num1,num2 = compare(c=z,a=x,b=9)#順序可以改變
#輸出結果如下:
最大值是9,最小值是1
函式執行完畢,有可能需要對程式傳出一些回傳值串列,具體由return而定,回傳值可以是0個,1個,多個,當回傳多個引數時,這些引數形成了一個元組資料型別,由小括號和逗號分隔,例如(a,b,c),元組和函式、整數、字串等一樣,是Python內置的資料型別,我們將在后續的課程中慢慢討論,
函式可以沒有回傳值,當回傳值是多個的時候,可以使用多個變數將回傳值依次賦值給這些變數,在上例中已經演示過,不再重復演示,
3.變數作用域
根據程式中變數的所在位置和作用范圍,可以將其分為全域變數和區域變數,全域變數值橫跨多個函式,在整個程式中存在并發揮作用的變數;而區域變數則是指在一個函式的內部存在,并只作用于這個函式內部,函式執行完畢后便被記憶體釋放,不在存在的變數,
例如如下代碼:
def compare(a,c,b=2):
ma = max(a,b,c)#ma和mi都是區域變數
mi = min(a,b,c)#區域變數誕生于函式內部
return ma,mi#函式執行完畢后也將消失
x = 1#x,z,num1,num2都是全域變數
z = 3#全域變數自宣告后除非主動消除,否則一直存在,
num1,num2 = compare(c=z,a=x,b=9)#順序可以改變
在函式內使用全域變數需要使用global保留字,使用方法如下:
global <全域變數名>
演示代碼如下:
s = "Python真簡單啊"
def f():
#使用global保留字表明s是前面已經宣告過的全域變數s
global s
print(s)
f()
#輸出結果如下:
Python真簡單啊
使用global保留字宣告變數的作用域是Python語言中少有的需要再次宣告的情形,由于作用域不同,這種宣告不能省略,
4.代碼復用
函式是程式的一種基本抽象方式,它將一系列代碼組織起來通過命名供其他程式使用,這種封裝的最直接好處就是能夠很好的實作代碼復用,當需要頻繁的使用某種操作或是功能時,將這種操作或功能撰寫成函式封裝起來,需要用的時候直接呼叫函式而不需要將該功能再寫一遍,大大提高了編程效率,
以函式式編程為基礎的模塊化設計程式,就是通過函式的封裝功能將程式劃分為主程式和若干子程式,通過主程式和子程式之間的關系,將各個獨立的功能程式組成一個有機可可協同的整體程式,因此,模塊化設計以功能塊為基本單位,一般有兩個基本要求:
緊耦合:盡可能合理劃分功能塊,各個功能塊內部耦合緊密,
松耦合:模塊間關系盡可能簡單,各個功能塊之間耦合松散,
在編程中,耦合性指程式結構中各模塊相互關聯的程度,它取決于各模塊間介面(即實作模塊相連的入口,能體現兩個功能模塊之間的關系)的復雜程度和呼叫方式,耦合性是影響軟體復雜程度和設計質量的一個重要因素,緊耦合指模塊或系統間關系緊密,存在較多或復雜的相互呼叫,緊耦合的缺點在于更新一個模塊可能導致其他模塊變化,復用較困難,松耦合一般基于訊息或協議實作,系統間互動簡單,
松耦合代表了模塊化,從系統觀點來看,松耦合是程式的總體設計原則,也是函式使用的重要指導,
使用函式只是模塊化設計的必要非充分條件,根據計算需求合理劃分函式十分重要,一般來說,完成特定功能或被經常復用的一組陳述句應該采用函式來封裝,并盡可能減少函式間引數和回傳值的數量,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/261975.html
標籤:Python
上一篇:Python資料型別和型別轉換
下一篇:PHP中的“多載”是個啥?
