python3 函數
函數也叫方法,比如你用手機打電話就是一個函數,你只管用就好,裏面的功能別人已經幫你研發好了,你只需要輸入手機號,按下撥打就好了,這個概念用在代碼裏尤為重要,比如重復某個功能,比如用戶輸入,你要判斷用戶的輸入不能為空吧,那麽這個你可以定義一個函數,就是用來判斷用戶的輸入是否為空,每次調用一下就可以,假如現在校驗用戶輸入的需求變化了,那麽你直接維護這個函數就好,沒必要再去所有的代碼裏找這個校驗,一個個的去改,所以函數有以下兩點顯而易見的優點:
1.重復代碼精簡,簡化復用性代碼的編寫,將重復性代碼寫成函數,要用的時候調用即可;
2.方便以後維護,你改一個函數,所有調用這個函數的地方的功能都能及時更新,避免修改代碼遺漏
函數在前面的字符串方法已經接觸過了,像strip()這些,就是python內置的一些函數,當然還有很多,這些函數python已經幫我們寫好,直接用就好了,這樣是不是很方便,什麽時候需要什麽時候就調用。顯而易見,函數要調用的時候才會執行,調用函數就是在函數名後加()就可以調用了,像strip()這些。
1.函數初識
定義函數的時候,寫的入參叫做形參;調用函數的時候,傳的值叫做實參:
def sayName(name,age,sex): #name,age,sex就是形式參數 # name,age,sex函數的參數類型是位置參數、必填參數 print(‘姓名: %s‘%name) print(‘年齡: %s‘%age) print(‘性別: %s‘%sex) # 上面這個就是函數體 sayName(‘星星‘,18,‘男‘) #‘星星‘,18,‘男‘這三個就是實際參數,調用的時候傳進來的參數 #打印結果: # 姓名: 星星 # 年齡: 18 # 性別: 男
2.函數return
函數如果需要返回值,用return即可,有兩點需要註意:
1.函數裏,只要遇到return就結束,不會再往下運行
2.如果函數沒有指定return返回值,那麽函數默認返回的是None
def cal1(a,b): returna+b return a*b def cal2(a,b): print(‘函數內a,b運行結果:‘,a+b) print(‘cal1函數return結果:‘,cal1(1,2)) print(‘cal2函數return結果‘,cal2(1,2)) #運行結果 # cal1函數return結果: 3 #因為函數裏ruturn了a+b的結果,所以這裏的結果是3 # 函數內a,b運行結果: 3 #這個是函數體內的運行情況 # cal2函數return結果 None #因為函數裏沒有ruturn,所以這裏的結果是None
3.函數即變量
從零單排0中介紹到的變量,在內存裏開放一個地方存變量,函數也是一樣,也是變量,存在內存裏的摸個地方,調用直接就是函數名+(),就調用了,看一個而有趣的調用方法,先定義一個字典,value存函數名,根據key來調用相應的函數,詳情見:http://www.cnblogs.com/znyyy/p/7670081.html
def play(): print(‘出去浪‘) def study(): print(‘好好學習‘) def_method={‘1‘:play,‘2‘:study} while True: choice=input(‘請輸入你的選擇:1代表出去浪;2代表好好學習\n‘) if choice==‘1‘ or choice==‘2‘: def_method[choice]() break else: print(‘請輸入正確的選擇!‘) continue 復制代碼
4.入參類型
函數的入參有很多類型,上面已經了解過位置參數,還有默認參數,可變參數,關鍵字參數。
註意:參數有順序,如果上述四種參數你都有用,那麽參數類型順序必須是:位置參數->默認參數->可變參數->關鍵字參數,否則報錯。
1.位置參數,這個參數就和格式化輸出裏的占位一樣,形參先把位置站好,然後就等著用戶調用的時候輸入實參,排隊填坑,如果實參和形參個數不一致,多了或者少了都會報錯,如下:
def add(a,b): print(‘%s+%s=%s‘%(a,b,a+b)) return a*b add(1,2) #打印結果:1+2=3 add(6,2) #打印結果:6+2=8 add(1,2,3) #打印結果:報錯,參數多了 add(2) #打印結果:報錯,參數少了
2.默認參數,這個參數就是程序會先給一個默認的,不傳不會報錯,會直接用默認的這個參數值,如果傳了就用你傳的這個值;等於是定義函數的時候先定義了一個參數變量,調用時如果沒傳就用之前定義好的,如果傳了就是覆蓋之前的值,用傳入的參數值:
# def multi(a,b=2): # print(‘%s**%s=%s‘ % (a, b, a ** b)) # multi(2) #不傳的時候默認b=2,這裏求的是平方 # multi(3) #不傳的時候默認b=2,這裏求的是平方 # multi(2,3) #傳的時候b=3了,這裏求的是立方 # multi(2,b=4) #和上面的這個調用時一樣的,但是一般這樣寫,如果默認參數較多時,不會因為位置而出錯 # multi(b=4,2) #報錯,位置參數必須在前 #運行結果: # 2**2=4 # 3**2=9 # 2**3=8 # 2**4=16
3.可變參數,這裏一般用的少,可變就是參數是變化的,考慮到了程序的擴展性,定義函數的時候並不確定會有多少個參數,這裏就用到了可變參數,既然可變,那麽在調用函數的時候也是可以不輸入的:
#可變參數 def user(name,passwd,*args): #一般是用args來命名,當然也可以用其他你想要的名字 print(‘用戶名:%s,密碼:%s‘%(name,passwd)) print(‘還有屬性如下:\n‘,args) #這裏的args,就是用戶輸入參數的一個元祖 # user(‘星星‘,123456,‘男‘,‘180cm‘,‘60kg‘) # 打印結果: # 用戶名:星星,密碼:123456 # 還有屬性如下: # (‘男‘, ‘180cm‘, ‘60kg‘)
4.關鍵字參數,也不是必填的,他是一個key-value的字典形式:
#關鍵字參數 def user(name,passwd,**kwargs): #一般是用args來命名,當然也可以用其他你想要的名字 print(‘用戶名:%s,密碼:%s‘%(name,passwd)) print(‘還有屬性如下:\n‘,kwargs) #這裏的args,就是用戶輸入參數的一個字典 user(‘星星‘,123456,sex=‘男‘,height=‘180cm‘,weight=‘60kg‘) # 打印結果: # 用戶名:星星,密碼:123456 # 還有屬性如下: # {‘height‘: ‘180cm‘, ‘sex‘: ‘男‘, ‘weight‘: ‘60kg‘}
5.變量作用域
變量作用域有四種:全局作用域,局部作用域,內建作用域,閉包函數外的函數中,後兩者用的少,全局作用域和局部作用域概念用的多。全局作用域就是變量在所有的範圍都可以用,比如在代碼開始定義一個變量,那麽不論是在函數外部還是內部都可以用這個變量;局部作用域就是只能在某個區域內才能用,除了這個區域就用不了了,比如函數內定義的變量只能在函數體內用,出了函數就用不了了。(建議不要用全局變量,不安全,所有人都可以修改)
#全局作用域 hys=[‘屏幕‘,‘主機‘] #全局變量 def yxg(thing): hys.append(thing) #函數體內可以用全局變量hys yxg(‘麥克‘) print(hys) #打印結果:[‘屏幕‘, ‘電腦‘, ‘麥克‘] #局部作用域 def yxg(thing): desk = [‘顯示器‘, ‘方便面‘] # 局部變量 desk.append(thing) #函數體內修改局部變量 yxg(‘鍵盤‘) print(desk) #函數體外調用局部變量報錯
值得一提的是,當全局變量是一個不可編輯的參數時,需要先申明才可以用全局變量(str/int/float等不可變變量函數在調用全局變量時,需要global才可以修改):
#不可變變量的全局變量引用,如int、float、str money=500 def chage(): money=1000 print(‘函數內的money:‘,money) #打印結果是 1000,因為函數內部作用域中money=1000,不能修改外面的money chage() print(‘函數外的money:‘,money) #打印結果是 500,因為函數不可以修改外部作用域中的不可變變量的全局變量引用,如int、float、str def chage(): global money #global後就可以引用了,這就申明了money是一個全局的變量,函數內可以修改 money = 1000 print(‘函數內的money:‘, money) #打印結果是 1000 chage() print(‘函數外的money:‘,money) #打印結果是 1000,因為global申明了全局變量,所以可以修改
更詳細的變量作用域見:http://www.cnblogs.com/znyyy/p/7670081.html
6.函數叠代
函數叠代,就是自己調用自己,一個死循環,一直調用下去,最多叠代999次,超過999程序自動停止運行(while沒有次數限制)。既然這樣,那麽叠代肯定要有一些特性才可以正常運用:
1. 必須有一個明確的結束條件
2. 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少
3. 遞歸效率不高,遞歸層次過多會導致棧溢出(在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出)
#函數叠代,就是自己調用自己,一個死循環,調用下去: def dd(): print(‘大雷好帥‘) dd() #函數內,又調用了函數本身,那麽就會一直調用下去 dd() #叠代函數最多會調用999次,這裏會打印999次“大雷好帥”
用叠代函數寫斐波拉契數列:[1, 1, 2, 3, 5, 8, 13, 21, 34],數列從第3項開始,每一項都等於前兩項之和。
先用以前的知識來寫:
list = [] def fb(num): a=1 b=1 while num>0: list.append(a) a,b=b,a+b num-=1 fb(9) print(list)
用叠代來寫:
list = [] a = 1 b = 1 def fb(num): global a,b list.append(a) a,b=b,a+b num-=1 if num>0: fb(num) fb(5) print(list)
更多函數剖析詳見:http://www.cnblogs.com/znyyy/p/7670081.html
python3 函數