python學習筆記四——函數
一、函數是什麽?
函數一詞來源於數學,但編程中的「函數」概念,與數學中的函數是有很大不同的,編程中的函數在英文中也有很多不同的叫法。在BASIC中叫做subroutine(子過程或子程序),在Pascal中叫做procedure(過程)和function,在C中只有function,在Java裏面叫做method。
定義: 函數是指將一組語句的集合通過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名即可。
二、使用函數的好處:
1、簡化代碼
2、提高代碼的復用性
3、代碼可擴展
三、python中函數的定義:
定義函數使用def關鍵字,後面是函數名,函數名不能重復
1 語法: 2 3def functionname( parameters): #沒有參數可以不寫() 4 5 "函數_文檔字符串" #存放函數說明 6 7 function_suite 8 9 return [expression] #沒有返回值可以不加[]內容,也可以省略return
1 2 3 def fun():#定義一個函數,後面是函數名 4 print("Hello World")#函數體
四、函數的參數
函數在調用的時候,可以傳入參數,有形參和實參
形參:
形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只在函數內部有效。
實參:
實參可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須有確定的值,以便把這些值傳送給形參。函數調用結束返回主調用函數後則不能再使用該形參變量。
1 def calc(x,y):#定義一個函數,參數有x和y,x和y就是形參 2 print(x*y)#輸出x乘以y的值 3 calc(5,2)#調用上面定義的函數,5和2就是實參
函數的四種形參類型:
位置參數:
位置參數,字面意思也就是按照參數的位置來進行傳參,比如說上面的calc函數,x和y就是位置參數,位置參數是必傳的,
有幾個位置參數在調用的時候就要傳幾個,否則就會報錯了,那如果有多個位置參數的話,記不住哪個位置傳哪個了怎麽辦,可以使用位置參數的名字來指定調用
比如說上面的那個calc函數也可以使用calc(y=1,x=2)這樣來調用,這種調用方式叫做關鍵字傳參
默認參數:
默認參數就是在定義形參的時候,給函數默認賦一個值,比如說數據庫的端口這樣的,默認給它一個值,這樣就算你在調用的時候沒傳入這個參數,它也是有值的
so,默認參數不是必填的,如果給默認參數傳值的話,它就會使用你傳入的值。如果使用默認值參數的話,必須放在位置參數後面定義。
1 def conn_mysql(user,passwd,port=3306):#定義一個連接mysql的方法,雖然這個方法並沒有連接mysql,我只是舉個默認值參數的例子,port就是一個默認值參數 2 print(user,passwd,port) 3 coon_mysql(‘root‘,‘123456‘)#沒指定默認值 4 coon_mysql(‘root‘,‘123456‘,port=3307)#指定默認值參數的值
1 def my(name,sex=‘女‘): 2 #name 必填參數、位置參數 3 #sex 默認值參數 4 #可變參數 5 #關鍵字參數 6 pass
非固定參數:
上面的兩種位置參數和默認參數都是參數個數是固定的,如果說我一個函數,參數不是固定的,我也不知道以後這個函數會擴展成啥樣,可能參數越來越多,這個時候如果再用固定的參數,那後面程序就不好擴展了,這時候就可以用非固定參數了,非固定參數有兩種,一種是可變參數,一種是關鍵字參數。
可變參數:
可變參數用*來接收,後面想傳多少個參數就傳多少個,如果位置參數、默認值參數、可變參數一起使用的的話,可變參數必須在位置參數和默認值參數後面。可變參數也是非必傳的。
1 def more_arg(name,age,sex=‘nan‘,*agrs):#位置參數、默認值參數、可變參數,可變參數會把後面多傳的參數都放到args這個元組中 2 #當然args名字是隨便寫的,不過一般我們都寫args 3 print(name,age,agrs) 4 more_arg(‘Marry‘,18,‘nv‘,‘python‘,‘China‘)#調用
1 def send_sms(*args): 2 #可變參數,參數組 3 #1、不是必傳的 4 #2、它把傳入的元素全部都放到了一個元組裏面 5 #3、不限制參數個數 6 #4、它用在參數比較多的情況下 7 for p in args: 8 print(p)
關鍵字參數:
關鍵字參數使用**來接收,後面的參數也是不固定的,想寫多少個寫多少個,當然也可以和上面的幾種一起來使用,如果要一起使用的話,關鍵字參數必須在最後面。
使用關鍵字參數的話,調用的時候必須使用關鍵字傳參。關鍵字參數也是非必傳的。
1 def kw_arg(name,**kwargs):#位置參數、關鍵字參數,調用的時候會把傳入的關鍵字參數放到kwargs這個字典中 2 print(name,kwargs) 3 kw_arg(‘sriba‘,sex=‘男‘,age=18)#調用,sex和age就是關鍵字調用
1 #關鍵字參數 2 3 def send_sms2(**kwargs): 4 #1、不是必傳的 5 #2、不限制參數個數 6 print(kwargs)
def my(name,country=‘China‘,*args,**kwargs): #1、位置參數 2、默認值參數 3、可變參數 4、關鍵字 print(name) print(country) print(args) print(kwargs) my(‘xiaojun‘,‘Japan‘,‘beijing‘,‘天通苑‘,color=‘紅色‘, age=32) my(‘xiaojun‘,‘beijing‘,‘天通苑‘, color=‘紅色‘,age=32) # 輸出 : xiaojun Japan (‘beijing‘, ‘天通苑‘) {‘age‘: 32, ‘color‘: ‘紅色‘} xiaojun beijing (‘天通苑‘,) {‘age‘: 32, ‘color‘: ‘紅色‘}
五、函數的返回值
每個函數都有返回值,如果沒有在函數裏面指定返回值的話,在python裏面函數執行完之後,默認會返回一個None,函數也可以有多個返回值,如果有多個返回值的話,會把返回值都放到一個元組中,返回的是一個元組。
為什麽要有返回值呢,是因為在這個函數操作完之後,它的結果在後面的程序裏面需要用到。
函數中的返回值使用return,函數在遇到return就立即結束。
1 #return 有2個作用 2 #1、結束函數,只要函數裏面遇到return,函數立即結束運行 3 #2、返回函數處理的結果
1 def calc(x,y):#這個就是定義了一個有返回值的函數 2 c = x*y 3 return c,x,y 4 res = calc(5,6)#把函數的返回結果賦值給res 5 print(res)
六、局部變量和全局變量
一個程序的所有的變量並不是在哪個位置都可以訪問的。訪問權限決定於這個變量是在哪裏賦值的。變量的作用域決定了在哪一部分程序你可以訪問哪個特定的變量名稱。
兩種最基本的變量作用域如下:全局變量、局部變量
局部變量是函數內部定義,僅在函數內有效。
全局變量在函數外部定義,可以被其他程序段調用。
局部變量意思就是在局部生效的,出了這個變量的作用域,這個變量就失效了,比如上面的c就是一個局部變量,出了這個函數之後,就沒有c這個值了
全局變量的意思就是在整個程序裏面都生效的,在程序最前面定義的都是全局變量,全局變量如果要在函數中修改的話,需要加global關鍵字聲明,如果是list、字典和集合的話,則不需要加global關鍵字,直接就可以修改。
函數內部通過global可以強制定義全局變量,當函數調用時全局變量生效。
1 name = ‘marry‘#字符串全局變量 2 names = []#list全局變量 3 print(name) 4 print(names) 5 def test(): 6 global name #修改name的值就需要用global關鍵字 7 name = ‘Sriba‘ 8 names.append(name)#修改全局變量names的值 9 return names 10 test()調用函數 11 print(‘修改後‘,name) 12 print(‘修改後names‘,names)
1 修改後 Sriba 2 修改後names [‘Sriba‘]
七、遞歸調用
在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數。
遞歸調用的意思就是,在這個函數內部自己調用自己,就有點循環的意思,遞歸最多遞歸999。
寫個遞歸,如下:
def test1(): num = int(input(‘please enter a number:‘)) if num%2==0:#判斷輸入的數字是不是偶數 return True #如果是偶數的話,程序就退出了,返回true print(‘不是偶數請重新輸入!‘) return test1()#如果不是偶數的話繼續調用自己,輸入值 print(test1())#調用test
1 #遞歸的意思函數自己調用自己 2 #遞歸最多遞歸999 3 count = 0 4 def say(): 5 global count 6 count+=1 7 print(‘say‘) 8 print(count) 9 say() 10 say() # 輸出會報錯 死循環 超出了9999
遞歸調用的特性:
1. 必須有一個明確的結束條件
2. 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少
3. 遞歸效率不高,遞歸層次過多會導致棧溢出(在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出)
八、高階函數
什麽是高階函數呢,如果一個函數的參數是一個函數的話,那麽這個函數就是一個高階函數,說起來比較懵逼,下面一段代碼就理解了
1 def s_int(n): 2 #這個函數的作用是把傳入的參數類型轉換成int類型 3 return int(n) 4 def add(x,y,z): 5 #這個函數的意思,接收3個參數,x,y,z,z是一個函數 6 print(z(x)+z(y))#這個執行過程是這樣的,z是一個函數,把x和y的值傳給z,然後用z函數的返回值把兩個值相加 7 add(‘8‘,‘9‘,s_int)#調用,傳入x和y的值,再把上面的那個定義好的函數傳進去
輸結果 為 17
#return 有2個作用
#1、結束函數,只要函數裏面遇到return,函數立即結束運行
#2、返回函數處理的結果
python學習筆記四——函數