函數的定義與使用
>函數的理解與定義
函數是一段代碼的表示
-函數是一段具有特定功能的、可重用的語句組
-函數是一種功能的抽象,一般函數表達特定功能
-兩個作用:降低編程難度 和 代碼復用
def <函數名>(<參數(0個或多個)>) :
<函數體>
return <返回值>
#計算n! def fact(n) : #fact 函數名;n 參數 s = 1 for i in range(1, n+1): s *= i return s # s 返回值
-函數定義時,所指定的參數是一種占位符
-函數定義后,如果不經過調用,不會被執行
-函數定義時,參數是輸入、函數體是處理、結果是輸出(IPO)
>函數的使用及調用過程
調用是運行函數代碼的方式
#接上段代碼 a=fact(10)
-調用時要給出實際參數
-實際參數替換定義中的參數
-函數調用后得到返回值
>函數的參數傳遞
參數個數:函數可以有參數,也可以沒有,但必須保留括號
def fact() : print("我是一個沒有參數的函數")
可選參數傳遞:函數定義時可以為某些參數指定默認值,構成可選參數
def <函數名>(<非可選參數>,<可選參數>) :
<函數體>
return <返回值>
#計算 n!//m def fact(n, m=1) : #m=1為可選參數 s = 1 for i in range(1, n+1): s *= i return s//m #fact(10) 3628800 #fact(10,5) 725760
可變參數傳遞
函數定義時可以設計可變數量參數,即不確定參數總數量
def <函數名>(<參數>,*b) :
<函數體>
return <返回值>
#計算 n!乘數 def fact(n, *b) : #*b可變參數 s = 1 for i in range(1, n+1): s *= i for item in b: s *= item return s # fact(10,3) 10886400 #fact(10,3,5,8) 435456000
參數傳遞的兩種方式:函數調用時,參數可以按照位置或名稱方式傳遞
def fact(n, m=1) : s = 1 for i in range(1, n+1): s *= i return s//m # fact( 10,5 ) 725760 # fact( m=5,n=10 ) 725760
>函數的返回值
函數可以返回0個或多個結果
-return保留字用來傳遞返回值
-函數可以有返回值,也可以沒有,可以有return,也可以沒有
-return可以傳遞0個返回值,也可以傳遞任意多個返回值
def fact(n,m=1): s=1 for i in range(1,n+1) s*=i return s//m,n,m #fact(10,5) (725760,10,5)
#a,b,c=fact(10,5)
#print(a,b,c)
#725760 10 5
>局部變量與全局變量
n, s = 10, 100 #n,s時全局變量 def fact(n) : s = 1 #fact()函數中的n s是局部變量 for i in range(1, n+1): s *= i return s print(fact(n), s) #n,s是全局變量 #3628800 100
規則1:局部變量和全局變量是不同變量
-局部變量是函數內部的占位符,與全局變量可能重名但不同
-函數運算結束后,局部變量被釋放
-可以使用global保留字在函數內部使用使用全局變量
n, s = 10, 100 #n,s時全局變量 def fact(n) : global s #fact()函數中使用global保留字聲明 此處s是全局變量s for i in range(1, n+1): s *= i return s print(fact(n), s) #此處全局變量s是被函數修改 #362880000 362880000
規則2:局部變量為組合數據類型且未創建,等同於全局變量
ls = ["F", "f"] #通過使用[]真實創建了一個全局變量列表ls def func(a) : ls.append(a) #此處ls是列表類型,未真實創建 則等同於全局變量 return func("C") #局部變量ls被修改 print(ls) # ['F','f','C']
ls = ["F", "f"] #通過使用[]真實創建了一個全局變量列表ls def func(a) : ls = [] #此處ls是列表類型,真實創建ls是局部變量 ls.append(a) return func("C") #局部變量ls被修改 print(ls) #['F','f']
使用規則
-基本數據類型,無論是否重名,局部變量與全局變量不同
-可以通過global保留字在函數內部聲明全局變量
-組合數據類型,如果局部變量未真實創建,則是全局變量
>lambda函數
lambda函數返回函數名作為結果
-lambda函數是一種匿名函數,即沒有名字的函數
-使用lambda保留字定義,函數名是返回結果
-lambda函數用於定義簡單的、能夠在一行內表示的函數
<函數名> = lambda <參數> : <表達式>
等價於
def <函數名> (<參數>):
<函數體>
return <返回值>
f=lambda x,y:x+y f=(10,15) #結果:25 f=lambda:"lambda函數" print(f()) #結果:lambda函數
謹慎使用lambda函數
-lambda函數主要用作一些特定函數或方法的參數
-lambda函數有一些固定的使用方式,建議逐步掌握
-一般情況,建議使用def定義的普通函數
代碼復用與函數遞歸
>代碼復用與模塊化設計
把代碼當成資源的抽象
-代碼資源化:程序代碼是一種用來表達計算的“資源”
-代碼抽象化:使用函數等方法對代碼賦予更高級別的定義
-代碼復用:同一份代碼在需要時可以被重復使用
函數 和 對象 是代碼復用的兩種主要形式
函數:將代碼命名在代碼層面建立了初步抽象
對象:屬性和方法 <a>.<b> 和<a>.<b>( )在函數之上再次組織進行抽象
分而治之
-通過函數或對象封裝將程序划分為 模塊及 模塊間的表達
-具體包括:主程序、子程序和子程序間的關系
-分而治之:一種分而治之、分層抽象、體系化的設計思想
緊耦合 松耦合
-緊耦合:兩個部分之間交流很多,無法獨立存在
-松耦合:兩個部分之間交流少,可以獨立存在
-模塊內部緊耦合、模塊之間松耦合
>函數遞歸的理解
函數定義中調用函數自身的方式
兩個關鍵特征
-鏈條:計算過程存在遞歸鏈條
-基例:存在一個或多個不需要再次遞歸的基例
類似數學歸納法
-數學歸納法
-證明當n取第一個值n0時命題成立
-假設當nk時命題成立,證明當n=nk+1時命題也成立
-遞歸是數學歸納法思維的編程體現
>函數遞歸的調用過程
def fact(n): if n==0: return 1 else: return n*fact*(n-1)
函數+分支語句
-遞歸函數本身是一個函數,需要函數定義方式描述
-函數內部,采用分支語句對輸入參數進行判斷
-基例和鏈條,分別編寫對應代碼
>函數遞歸實例解析
將字符串s反轉后輸出
def rvs(s): if s == "": return s slse: return rvs(s[1:])+s[0]
斐波那契數列:一個經典的數列
def f(n): if n==1 or n==2 : return 1 else: return f(n-1)+f(n-2)