函數能提高應用的模塊性,和代碼的重復利用率。在很多高級語言中,都可以使用函數實現多種功能。在之前的學習中,相信你已經知道Python提供了許多內建函數,比如print()。同樣,你也可以自己創建函數,這被叫做用戶自定義函數,來實現定制的功能。
一、函數的基本使用
1.函數的定義
函數是一段具有特定功能的、可重用的語句組,用函數名來表示並通過函數名進行功能調用。
函數能夠完成特定功能,與黑盒類似,對函數的實用不需要了解函數內部實現原理,只要了解函數的的輸入和輸出方式即可。所以說,函數是一種功能抽象。
使用函數有兩個目的:降低編程難度和代碼重用。所以在編程中的復雜功能可以使用函數實現。
其中,Python使用 def 保留字定義了一個函數,語法如下:
def <函數名> (<參數列表>):
<函數體>
return <返回值列表>
注:當參數類表中有多個參數,默認情況下,參數值和參數名稱是按函數聲明中定義的順序匹配起來的。
2.函數的調用過程
程序調用一個函數需執行一下4個步驟:
(1)調用程序在調用處暫停執行。
(2)在調用時將實參復制給函數的形參。
(3)執行函數體語句。
(4)函數調用結束給出返回值,程序回到調用前的暫停處繼續執行。
從函數的調用過程中,人們引申出了函數式編程這個概念。函數式編程是一種編程范式,常見的編程范式還包括命令式編程和面向對象編程等。函數編程的主要思想是把程序過程通過使用一系列函數能夠使代碼編寫更簡潔、更易於理解,是中小規模軟件項目中最常見的一種編程方式。
二、函數的參數傳遞
1.可選參數和可變數量參數、
可選參數
在定義函數時,如果有些參數存在默認值,即部分函數不一定需要調用程序輸入,可以在定義函數時直接為這些參數指定默認值。當函數被調用時,如果沒有傳入對應的參數值,則使用函數定義時的默認值替代。例如:
使用默認參數:
def printf(str, times = 3): print(str * times)
>>>printf("hello")
hello
hello
hello
輸入參數
def printf(str, times = 3): print(str * times) >>>printf("hello",2)
hello
hello
可變量參數
在函數定義時,也可以設計可變量參數,通過在參數前增加星號(*)實現。帶有星號的可變參數只能出現在參數列表的最后。調用時,這些參數被當作元組類型傳遞到函數中。
例如:
def printf(times,*b): print(b*times) printf(2,1,2,3) >>>(1, 2, 3, 1, 2, 3)
2.參數的位置和名稱傳遞
Python中提供了按照形參名稱輸入實參的方式,例如
return = fuc(x1=2, x2=5, x3=8) #其中參數由函數 fuc 決定
由於調用函數時指定了參數名稱,所以參數之間的順序可以任意調整。
3.函數的返回值
return語句用來退出函數並將程序返回被調用的位置繼續執行。
同時,函數可以沒有return,此時函數並不返回值。函數也可以用return返回多個值,多個值以元組類型保存。
4.函數對變量的作用
一個程序中的變量包括兩類:全局變量和局部變量。全局變量指在函數之外定義的變量,一般沒有縮進,在程序執行全過程有效。局部變量指在函數內部使用的變量,僅在函數內部有效,當函數退出時變量將不存在。
其中Python函數對變量的作用遵守如下原則:
(1)簡單數據類型變量無論是否與全局變量重名,僅在函數內部創建和使用,函數退出后變量被釋放,如有全局同名變量,其值不變。
(2)簡單數據類型變量在用 global 保留字聲明后,作為全局變量使用,函數退出后該變量保留且值被函數改變。
(3)對於組合數據類型的全局變量,如果在函數內部沒有被真實創建的同名變量,則函數內部可以使用並修改全局變量的值。
(4)如果函數內部真實創建了組合數據類型變量,無論是否有同名全局變量,函數僅對局部變量進行操作,函數退出后局部變量被釋放,全局變量值不變。
三、代碼復用和模塊化設計
函數是程序的一種抽象,它通過封裝實現代碼復用。可以利用函數對程序進行模塊化設計。
程序由一系列代碼組成,如果代碼是順序但無組織的,不僅不利於閱讀和理解,也很難進行維護和升級。因此,把代碼當成資源的抽象,形成易於理解的結構。
函數是程序的一種基本抽象方式,它將一系列代碼組織起來通過命名供其他程序使用。函數封裝的直接好處是代碼復用,任何其他代碼只要輸入參數即可調用函數,從而避免相同代碼在被調用處重復編寫。代碼復用產生了另一個好處,當更新函數時,所有被調用處的功能都能被更新。
模塊化設計指通過函數或對象的封裝功能將程序划分成主程序、子程序和子程序間關系的表達。模塊化設計是使用函數和對象設計程序的思考方法,以功能塊為基本單位,一般有以下兩個基本要求:
(1)緊耦合:盡可能合理划分功能塊,功能塊內部耦合緊密。
(2)松耦合:模塊間關系盡可能簡單,功能塊之間耦合度低。
概括來說,就是模塊內部緊耦合、模塊之間松耦合
四、函數的遞歸
1.遞歸的定義
函數作為一種代碼封裝,可以被其他程序調用,當然,也可以被函數內部代碼調用。這種函數定義中調用函數自身的方式稱為遞歸。
遞歸的兩個關鍵特征:
(1)存在一個或多個基例(問題的最小規模下的解),基例不需要再次遞歸,它是確定的表達式。
(2)所有遞歸要以一個或多個基例結尾。
2.遞歸的使用方法
實例:階乘的計算。
def fact(n): if n == 0: return 1 else: return n * fact(n-1) n=eval(print()) print(fact(abs(int(n))))
輸入:
>>>10 26288800