1.形參和實參
函數從調用的角度來說,分為形式參數和實際 參數。形參是指函數創建和定義過程中小括號里的參數;而實參指得是函數在被調用過程中傳遞進來的參數。如下所示
>>> def MyFirstFunction(name): '函數定義過程中的name是叫形參' #因為Ta只是一個形式,表示占據一個參數位置 print('傳遞進來的' + name + '叫做實參,因為Ta是具體的參數值!') >>> MyFirstFunction('小甲魚') 傳遞進來的小甲魚叫做實參,因為Ta是具體的參數值!
2.函數文檔(.__doc__)
給函數寫文檔是為了讓別人可以更好的理解你的函數,所以這是一個好習慣。函數文檔的作用是描述該函數的功能。
>>> def MyFirstFunction(name):
'函數定義過程中的name是叫形參'
#因為Ta只是一個形式,表示占據一個參數位置
print('傳遞進來的' + name + '叫做實參,因為Ta是具體的參數值!')
>>> MyFirstFunction.__doc__ #MyFirstFunction沒有()
'函數定義過程中的name是叫形參'
>>>
我們發現,在函數開頭寫下的字符串是不會打印出來的,但它作為函數的一部分存儲起來。這個稱為函數文檔字符串,它的功能跟注釋一樣。
與注釋不同的是,函數文檔字符串可以通過特殊屬性 ._ _doc_ _(注:._ _doc_ _兩邊分別是兩條下划線):
也可以使用help()函數查看函數的文檔
函數文檔寫在一個字符串里面,寫2個,只會打印出第一個,第二個不會打印打出,例如:
>>> def MyFirstFunction(name,age): '這是一個函數文檔' '用來記錄函數的使用記錄' print('班長:'+ name +',年齡:' + age) >>> MyFirstFunction.__doc__ '這是一個函數文檔' >>>
3.關鍵字參數
普通的參數叫做位置參數,使用位置參數可以解決程序員在調用一個函數時候,搞亂位置參數的順序,以至於函數無法按照預期實現的潛在問題。
>>> def saySome(name,words): print(name + "—>" +words) >>> saySomething("小甲魚","讓編程改變世界!") 小甲魚—>讓編程改變世界! >>> saySome("讓編程改變世界!","小甲魚") 讓編程改變世界!—>小甲魚
'為了不讓調用的參數位置弄混,加上關鍵字參數,就不會出錯了' >>> saySome(words="讓編程改變世界!",name="小甲魚") 小甲魚—>讓編程改變世界!
關鍵字參數其實就是在傳入實參時指定形參的變量名,在調用函數的時候使用的!
4.默認參數
默認參數就是在函數定義的時候,給形參賦予了默認值的參數:
>>> def saySome(name="小甲魚",words="讓編程改變世界!"): print(name + '—>' +words) >>> saySome() #調用函數時沒有參數,就會去找默認參數 小甲魚—>讓編程改變世界! >>> saySome("小魷魚","也可以改變世界") #重新賦予實參,會調用函數時會調用實參,不會調用默認的參數 小魷魚—>也可以改變世界
>>> def test1(name = '甲魚',age = '20'): print('語文老師的名字是:'+ name +',年齡:' + age) >>> test1() 語文老師的名字是:甲魚,年齡:20 >>> test1('youyu') 語文老師的名字是:youyu,年齡:20 >>> test1(name = 'lucu') 語文老師的名字是:lucu,年齡:20 >>>
使用默認參數的話,就可以不帶參數去調用函數。所以,它們之間的區別是:關鍵字參數是在函數調用的時候,通過參數名指定要賦值的參數,這樣做就不怕因為搞不清參數的順序而導致函數的調用出錯;而默認參數是在參數定義過程中,為形參賦初值,當函數調用的時候,不傳遞參數,則默認使用形參的初始值代替。
5.收集參數(可變參數)
表示Function(*param)
收集參數在大多數的時候被稱作可變參數,僅需要在參數前面加上星號(*)即可:
>>> def TestFun(*param): print('函數的長度是:',len(param)) print('第二個參數是:',param[1]) >>> TestFun(1,'hello',3.14) 函數的長度是: 3 第二個參數是: hello >>>
Python就是把標志為收集參數的參數們打包成一個元組。
注意:如果在收集參數的后面還需要指定其它參數,在調用函數的時候就應該使用關鍵字參數來指定,否則Python就都會把你的實參都列入收集參數的范疇。
>>> def TestFun(*param,dec): print('函數的長度是%d' % len(param)) print('最后一個參數是:',param[-1]) >>> TestFun(2,4,6,'world',7,8) Traceback (most recent call last): File "<pyshell#18>", line 1, in <module> TestFun(2,4,6,'world',7,8) TypeError: TestFun() missing 1 required keyword-only argument: 'dec' >>> TestFun(2,4,6,'world',7,dec=8) 函數的長度是5 最后一個參數是: 7 >>>
建議:
在參數中帶有收集參數是,可以將其它參數設置為默認參數,這樣不容易出錯
>>> def TestFun(*param,dec=9): print('函數的長度是%d' % len(param)) print('最后一個參數是:',param[-1]) >>> TestFun(2,4,6,'world',7,5) 函數的長度是6 最后一個參數是: 5 >>>
>>> def test(*param,keyname=8): print('收集參數是:',param) print('關鍵字參數是:',keyname) >>> test(1,2,3,4,9) 收集參數是: (1, 2, 3, 4, 9) 關鍵字參數是: 8 >>>
課后習題及答案
0.請問一下哪個是形參哪個是實參?
>>> def MyFun(x): return(x**3) y = 3 print(MyFun(y)) >>> MyFun(3) 27
x是形參,y是實參
1.函數文檔和直接用#為函數寫注釋有什么不同
函數文檔可以用屬性.__doc__調用,即Function.__doc__,
#注釋
2.使用關鍵字參數,可以避免什么問題的出現
可以避免調用函數是參數傳遞錯誤的問題
3.使用help(print)查看print()這個BIF有哪些默認參數?分別起到什么作用?
4.默認參數和關鍵字參數表面最大的區別是什么?
默認參數在函數定義時就賦值,關鍵字參數是在函數調用時賦值
動動手:
0.編一個符合以下要求的函數:
a)計算打印所有參數的和乘以基數(base=3)的結果
b)如果參數中最后一個參數為(base=5),則設定基數為5,基數不參與求和計算。
>>> def Sum_X_base(*param,base = 3): result = 0 for each in param: result += each if param[-1] == 5: base = 5 Sum = result *base return Sum >>> Sum_X_base(1,2,3) 18 >>> Sum_X_base(1,2,5) 40 >>>
1.尋找水仙花數
如果一個3位數等於其各位數字的立方和,則稱這個數為水仙花數,例如153=1^3+5^3+3^3,因此153是一個水仙花數,編寫一個程序,找出所有的水仙花數。
Narcissus [nɑːˈsɪsəs]:水仙
>>> def FoundNarcissus(): for each in range(100,1000): temp = each sum = 0 while temp: sum += (temp % 10)**3 temp = temp // 10 if (sum == each): return each >>> FoundNarcissus() 153 >>>
正確的代碼如下:
>>> def Narcissus(): for each in range(100,1000): temp = each result = 0 while temp: result += (temp %10)**3 temp = temp // 10 if (result == each): print(each) >>> Narcissus() 153 370 371 407 >>>
2.編寫一個函數findstr(),該函數統計一個長度為2的子字符串在另一個字符串中出現的次數,例如:假如輸入的字符串為:You cannot improve your past,but you can improve your future.Once time is wasted,life is wasted.子字符串為im,該函數執行后打印“子字符串在目標字符串中共常出現3次”。
def findStr(desStr, subStr): count = 0 length = len(desStr) if subStr not in desStr: print('在目標字符串中未找到子字符串!') else: for each1 in range(length-1): if desStr[each1] == subStr[0]: if desStr[each1+1] == subStr[1]: count += 1 print('子字符串在目標字符串中共出現次',count) desStr = input('請輸入目標字符串:') subStr = input('請輸入子字符串(兩個字符):') print(findStr(desStr, subStr))