# -*- coding:utf-8 -*- # ------函數(參數)------------- '''函數是組織好的,可以重複使用的,用來實現單一,或相關聯功能的代碼 定義函數用def語句,一次寫出函數名,括號,括號中的參數和冒號,然後在縮進塊中編寫函數體, 函數的返回用return返回 函數總有返回值,就算沒有return也會返回none 支持遞歸調用,但不能進行尾遞歸優化 一個完整的函數對象由函數和代碼兩部分組成。其中,PyCodeObject 包含了字節碼等執⾏行數據, ⽽而 PyFunctionObject 則爲其提供了狀態信息。 ''' #abs調用 print(123); #123,傳的參數類型和數量必須正確,否則報錯 #比較函數cmp(x,y) x<y return-1,x>y return 1,x=y return 1; print cmp(4,5); #-1 print cmp(5,4); #1 print cmp(5,5); #0 #數據類型轉換,如int()函數可以將其他數據類型轉換爲整數 a='12'; print type(a); #<type 'str'> print int(a); #12 print type(int(a)); #<type 'int'> print float(a); #12.0 print type(float(a)); #<type 'float'> print bool(0); #False #函數名就是指向一個函數對象的引用,可以把函數名賦值給一個變量,相當於給函數起別名 s = cmp #給cmp函數起別名s,s指向cmp函數 print s(5,4); #1 通過別名調用函數 #------------------------------------- def sayHello(): #定義函數sayhello print 'Hello world!' #函數塊 sayHello(); #Hello world! 調用 #-----函數參數-------- def output(x): print (x); if x >0: return x; else: return -x; output(-9); #-9 output('a'); #a #--參數檢查--參數個數不對,python解釋器會報錯,但是類型不對不會報錯(對於自定義函數) #內置函數abs()如果傳入字符串類型會檢查出來,而我們上例中定義的output()則無法檢查 # def outputs(x): # print (x); # if not isinstance(x,(int,float)): # raise TypeError('you have input a bad object'); # if x >0: # return x; # else: # return -x; # outputs('b'); # 這裏會應影響下面代碼的執行,所以我把這一塊全部注掉 ''' File "D:/pycharmhome/venv/demo5.12.27.py", line 51, in <module> File "D:/pycharmhome/venv/demo5.12.27.py", line 46, in outputs raise TypeError('you have input a bad object'); TypeError: you have input a bad object ''' #------ def printMax(a,b): if a>b: print a,'is the bigger one'; else: print b,'is bigger one'; printMax(3,4); #4 is bigger one x=1; y=2; printMax(x,y); #2 is bigger one printMax('c','b') #c is the bigger one 可以用參數檢查只數int類型 #------空函數--------- #pass 佔位符,用來標記空代碼塊。還沒有想好怎麼寫函數,可以先放一個pass不會報錯 def text(): pass; for i in xrange(1,10): pass; #------函數返回多個值-- import math def move(x,y,step,angle=0): nx = x + step * math.cos(angle); ny = y - step * math.sin(angle); return nx,ny; x,y = move(100,100,23,30); print x,y; #103.547783347 122.724727354 ''' 這是一個假象,函數返回的仍是一個值,返回值是一個tuple,在語法上tuple可以省略括號,而 多個變量可以同時接收一個tuple,按位置賦給對應的值,所以,python的函數返回多值其實就是 返回一個tuple,但寫起來方便 ''' #----------------------------------------------------------------------- #函數的參數 function parameters--- #上面例子中59行printmax函數就進行了傳參 def power(i): return i*i; print power(5) #25 #------- def power(i,n): s = 1; while n>0: n = n-1; #n控制循環次數,1*i*i*i..控制這裏i出現幾次 s = s*i; return s print power(5,2); #25 這是power(5)會報錯 #----設置默認參數 def power(i,n=2): s = 1; while n > 0: n = n-1; s=s*i; return s; print power(5); #25 print power(2,3); #8 當n>2時明確傳入n #-定義時,必選參數在前默認參數在後。否則報錯 #函數傳參方式靈活多變,可按照位置順序傳,也可以不關心位置命名來傳 def test(a,b): print a,b; test(1,'a'); #1 a test(b = 'a', a=1); #1 a #-默認參數的好處,簡化書寫,不用在調用的時候再輸入值 def stu(name,gender,age = 3,city = '西安'): print 'name:',name; print 'gender:',gender; print 'age:',age; print 'city:',city; stu('二大爺','man'); ''' name: 二大爺 gender: man age: 3 city: 西安 ''' ''' 注意:默認值參數必須指向不變的對象,否則在每次調用的時候他都會記住上次調用的值,當新 調用時會將之前的值和現在傳入的值同時輸出。下面看一個錯誤的例子 ''' def box(i,intlist = []): intlist.append(i); return intlist; print box(4); #[4] print box(3); #[4, 3] print box(5,[]);#[5] 顯示的提供實參不適用默認值是正確的 print box(5); #[4, 3, 5]再次使用默認值 print box(5); #[4, 3, 5, 5]再再次使用默認值 ''' 因爲這裏我用的是list作爲默認值,而list的長度可變,當每次調用的時候都會給裏面添加一個 數字i=?,則在下一次調用的時候list這個表裏都會有上次所添加的數字,來作爲這個box函數中 的默認參數。即第2次 intlist=[4],第3次 intlist=[4,3]... 而如果顯示的給出實參不提供默認值,相當於格式化這個表 即5=intlist,輸出的永遠只有一個數字 ''' #所以通常不用可變對象來作爲默認值 #可以用不變的None來修改上面的例子 def boxs(i,intlist = None): if intlist is None: intlist = []; intlist.append(i); return intlist; print boxs(3); #[3] print boxs(4); #[4] #------------------------------------------------------- #--可變參數-- def num(numbers): sum = 0; for n in numbers: sum = sum + n*n # return sum; print num([1,2,3]);#14 將參數組裝成一個list sum=1*1+2*2+3*3 print num((2,3)); #13 將參數組裝成一個tuple sum=2*2+3*3 #------用可變參數簡化調用---------------------------------------- def nums(*numbers): sum = 0; for n in numbers: sum = sum + n*n return sum; print nums(2,4); #20 print nums(); #0 可以傳0個參數 #--已經有一個tuple或list,調用可變參數 num = [2,2]; print nums(num[0],num[1]);#8 這樣比較麻煩 print nums(*num); #8 允許在list或者tuple前加*,把list或者tuple的元素變爲可變參數傳進去 #----------------------------------------------------- #--關鍵字參數--- # 可變參數允許傳入0或人一個參數,這些可變參數在函數調用是自動組裝爲一個tuple。而關鍵字 # 參數允許傳入0個或任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝爲一個dict def person(name,age,**kwargs): print 'name:',name,'age:',age,kwargs; print person('二大爺','77',qq = 123,email = '[email protected]'); # name: 二大爺 age: 77 {'qq': 123, 'email': '[email protected]'} #也可以先組裝一個dict,然後,把dict轉換爲關鍵字傳進去 kw = {'city':'xianyang', 'job':'teacher', 'qq':123} print person('二大爺',77,city = kw['city'],job=kw['job']); # name: 二大爺 age: 77 {'city': 'xianyang', 'job': 'teacher'} print person('二大爺',77,**kw); # name: 二大爺 age: 77 {'qq': 123, 'city': 'xianyang', 'job': 'teacher'} # -------參數組合-------------- def allbox(a,b,c=0,*args,**kwargs): print 'a:',a,'b:',b; #必選參數 print 'c:',c; #默認參數 print 'args:',args; #可變參數 print 'kwargs:',kwargs #關鍵字參數 print allbox(1,2); ''' a: 1 b: 2 c: 0 args: () kwargs: {} None ''' print allbox(1,2,3,'a','b','c',d = 4,e = 5); ''' a: 1 b: 2 c: 3 args: ('a', 'b', 'c') kwargs: {'e': 5, 'd': 4} ''' #也可以通過tuple和dict調用 args = (1,2,3,4,5); #list也行 kwargs = {'e':4}; print allbox(*args,**kwargs); ''' a: 1 b: 2 c: 3 args: (4, 5) kwargs: {'e': 4} ''' # -------補充----------- # 變參智能功能放在所有定義參數的尾部,切**kwargs必須是最後一個。 def tes(*arg,**kwargs): #可接收任意參數的函數 print arg; print kwargs; print tes(1,2,'a','b',c='c',d='d'); #位置(必選)、命名(關鍵字) ''' (1, 2, 'a', 'b') {'c': 'c', 'd': 'd'} ''' print tes('a'); #只傳位置參數 ''' ('a',) {} ''' print tes(a='a');#只傳命名(關鍵字)參數 ''' () {'a': 'a'} ''' #-----------可以展開序列類型和字典,將全部元素當多個實參使用。不展開僅是單個實參對象 def zk(a,b,*args,**kwargs): print a,b; print args; print kwargs; print zk(*xrange(1,7)); ''' 1 2 (3, 4, 5, 6) {} ''' #單個*用來展開序列類型,或者僅是字典的主鍵列表。**用來展開字典的值,如果沒有變參收集 # 展開後多餘的參數會引發異常.如上例把*args去掉就有異常; def zk_dic(a,b): print a; print b; dic = {'a':4,'b':5}; print zk_dic(*dic); ''' a b ''' print zk_dic(**dic); ''' 4 5 '''
函數---參數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.