首先,咱們要明確,函數的出現,目的就是爲了解決重複代碼的問題。python
接下來,舉個栗子來講明:程序員
老闆讓你寫一個監控程序,用來監控服務器的系統情況,當CPU,內存 ,磁盤等指標超出閾值的時候發郵件報警。編程
恩,就這麼一個需求,當時拿到手的時候特別高興,以爲我草,終於能夠寫代碼了,因而你寫了下面的代碼:服務器
while True函數式編程
if cpu利用率 > 90%:函數
#發送郵件spa
鏈接郵件服務器設計
發送郵件code
關閉鏈接blog
if disk > 90%:
#發送郵件
鏈接郵件服務器
發送郵件
關閉鏈接
if mem >80%:
#發送郵件
鏈接郵件服務器
發送郵件
關閉鏈接
完畢,你很激動,以爲這是今生寫的最多的Python代碼,不由暗暗竊喜,想到你把代碼提交給老大之後,老大驚訝的表情,你很享受,因而,次日,早早的,你提交了代碼,老大姓王,住你家隔壁,人送外號老王。
老王看了看你的代碼,說道,你這個重複代碼太多,每次報警都要從新寫一段發郵件的代碼,太low了,這樣幹 存在2個問題:
一、代碼重複過多,一個勁的copy 和paste不符合高端程序員的氣質。
二、不利用二次使用。
老王接着說,其實很簡單,只須要把重複的代碼提出來,放到一個公共的地方,起個名字,之後誰想用這段代碼,就能夠經過這個名字直接調用便可,以下:
def 發送郵件(內容) #發送郵件提醒 鏈接郵箱服務器 發送郵件 關閉鏈接 while True: if cpu >90%: 發送郵件(‘CPU報警’) if disk > 90%: 發送郵件(‘硬盤報警’) if mem >80%: 發送郵件(‘內存報警’)
你還別說,這麼一些確實省去了很多的重複代碼,並且還增長了可讀性。
說了這麼多,那麼函數究竟是什麼呢?
函數一詞來源於數學,但編程中的函數概念,與數學中的函數是有很大的不一樣的,編程中的函數在英文中也有不少不一樣的叫法。在BASIC中叫作subroutine(子過程或子程序),在Pascal中叫作procedure(過程)和function,在C中只有function,在Java中叫作method。
特性:
一、減小重複代碼
二、使程序變得可擴展
三、使程序變得易維護
語法定義:
def hanshuming():#函數名 print(「hehe」) sayhi() #調用函數
能夠帶參數:
#舉個栗子,把下面代碼改爲函數
a,b = 5,8 c = a**b print(c) #改爲函數 def calc(x,y): res = x**y return res # 返回函數執行的結果 c = calc(a,b) #結果賦值給c變量 print(c)
形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。所以,形參只在函數內部有效。函數調用結束返回主調用函數後則不能再使用該形參變量。
實參能夠是常量、變量、表達式、函數等,不管實參是何種類型的量,在進行函數調用時,它們都必須有肯定的值,以便把這些值傳送給形參。所以應預先用賦值,輸入等辦法使參數得到肯定值。
#改爲用函數
def calc(x,y): #形參 res = x**y return res c = calc(a,b) #實參 print(c)
舉個栗子
def sayhi(name,age,nationality="CN"): print("Hello,I am %s" % name,age,nationality ) sayhi("jixuege",22,"JP") 打印結果 Hello,I am jixuege 22 JP
說明:
上面不傳國籍就使用默認的,傳了就使用傳的參數。
非固定參數
若是函數在定義時不肯定用戶想傳入多少個參數,就能夠用非固定參數
*args
舉個栗子
def stu(name,age,*args): print(name,age,args) stu("jixuege",22) stu("jixuege",22,"dajiba","python") 輸出結果 jixuege 22 () jixuege 22 ('dajiba', 'python')
還有一個**args
def stu(name,age,*args,**kwargs): print(name,age,args,kwargs) stu("jixuege",22) stu("jixuege",22,"python","CN",sex="man",province="xinjiang") 輸出結果 jixuege 22 () {} jixuege 22 ('python', 'CN') {'province': 'xinjiang', 'sex': 'man'}
全局與局部變量的區別
在子程序中定義的變量稱爲局部變量,在程序的一開始定義的變量稱爲全局變量。
全局變量做用域是整個程序,局部變量做用域是定義該變量的子程序。
當全局變量與局部變量同名時:
在定義局部變量的子程序內,局部變量起做用;在其餘地方全局變量起做用。
想要獲取函數的執行結果,就能夠用return語句把結果返回
注意:
一、函數在執行過程當中只要遇到return語句,就會中止執行並返回結果,因此也能夠理解爲return語句表明着函數的結束。
二、若是未在函數中指定return,那這個函數的返回值爲none。
什麼叫作遞歸函數?
若是一個函數在內部調用本身自己,這個函數就是遞歸函數。
遞歸特性:
一、必須有一個明確的結束條件。
二、每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減小。
三、遞歸效率不高,遞歸層次過多會致使棧溢出。
舉個栗子
def calc(n): print(n) if int(n/2) == 0: return n return calc(int(n/2)) calc(10) 輸出結果 10 5 2 1
什麼是匿名函數?
匿名函數就是不須要顯示的指定函數。
舉個列子:
#這段代碼 def calc(n): return n**n print(calc(10)) #換成匿名函數 calc= lambda n:n**n print(calc(10)) 輸出結果 10000000000 10000000000
函數式Python內建支持的一種封裝,咱們經過把大段代碼拆成函數,經過一層一層的函數調用,就能夠把複雜任務分解成簡單的任務,這種分解能夠稱之爲面向過程的程序設計。函數就是面向過程的程序設計的基本單元。
記住:
函數式編程:講的是數學裏面的函數,跟我上面講的函數不是一回事。
變量能夠指向函數,函數的參數可以接受變量,那麼一個函數就能夠接受另外一個函數做爲參數,這種函數就叫高階函數
舉個栗子
def add(x,y,z): return z(x) + z(y) res = add(3,-6,abs) print(res) 打印結果 9