課時18:函式:靈活即強大

那是個好男孩發表於2018-08-13

目錄:

  一、形參和實參

  二、函式文件

  三、關鍵字引數

  四、預設引數

  五、收集引數

  六、課時18課後習題及答案

 

******************

一、形參和實參

******************

函式從呼叫的角度來說,分為形式引數和實際 引數。形參是指函式建立和定義過程中小括號裡的引數;而實參指得是函式在被呼叫過程中傳遞進來的引數。舉個例子:

>>> def MyFirstFunction(name):
    '函式定義過程中的name是叫形參'
    #因為Ta只是一個形式,表示佔據一個引數位置
    print('傳遞進來的' + name + '叫做實參,因為Ta是具體的引數值!')

>>> MyFirstFunction('小甲魚')
傳遞進來的小甲魚叫做實參,因為Ta是具體的引數值!

 

****************

二、函式文件

****************

給函式寫文件是為了讓別人可以更好的理解你的函式,所以這是一個好習慣。函式文件的作用是描述該函式的功能。

>>> def exchangeRate(dollar):
    """美元—>人民幣
    匯率暫定為6.5
    """
    return dollar * 6.5

>>> exchangeRate(10)
65.0

我們發現,在函式開頭寫下的字串是不會列印出來的,但它作為函式的一部分儲存起來。這個稱為函式文件字串,它的功能跟註釋一樣。

與註釋不同的是,函式文件字串可以通過特殊屬性_ _doc_ _(注:_ _doc_ _兩邊分別是兩條下劃線):

>>> exchangeRate(10)
65.0
>>> exchangeRate.__doc__
'美元—>人民幣\n\t匯率暫定為6.5\n\t'

另外,想用一個函式但不知道其用法時,會通過help()函式檢視函式的文件。因此,對自己的函式也可以如法炮製:

>>> help(exchangeRate)
Help on function exchangeRate in module __main__:

exchangeRate(dollar)
    美元—>人民幣
    匯率暫定為6.5

 

******************

三、關鍵字引數

******************

普通的引數叫做位置引數,使用位置引數可以解決程式設計師在呼叫一個函式時候,搞亂位置引數的順序,以至於函式無法按照預期實現的潛在問題。來看個例子:

>>> def saySomething(name,words):
    print(name + "—>" +words)

    
>>> saySomething("小甲魚","讓程式設計改變世界!")
小甲魚—>讓程式設計改變世界!
>>> saySomething("讓程式設計改變世界!","小甲魚")
讓程式設計改變世界!—>小甲魚
>>> saySomething(words="讓程式設計改變世界!",name="小甲魚")
小甲魚—>讓程式設計改變世界!

關鍵字引數其實就是在傳入實參時指定形參的變數名,儘管使用這種技巧要多打一些字,但隨著程式規模的越來越大、引數越來越多,關鍵字引數起到的作用就越明顯。

 

****************

四、預設引數

****************

預設引數就是在定義的時候賦予了預設值的引數:

>>> def saySomething(name="小甲魚",words="讓程式設計改變世界!"):
    print(name + '—>' +words)

    
>>> saySomething()
小甲魚—>讓程式設計改變世界!
>>> saySomething("DC","有時候最意想不到的人 才能做出最超乎想象的事")
DC—>有時候最意想不到的人 才能做出最超乎想象的事

使用預設引數的話,就可以不帶引數去呼叫函式。所以,它們之間的區別是:關鍵字引數是在函式呼叫的時候,通過引數名指定要賦值的引數,這樣做就不怕因為搞不清引數的順序而導致函式的呼叫出錯;而預設引數是在引數定義過程中,為形參賦初值,當函式呼叫的時候,不傳遞引數,則預設使用形參的初始值代替。

 

****************

五、收集引數

****************

收集引數在大多數的時候被稱作可變引數,僅需要在引數前面加上星號(*)即可:

>>> def test(*params):
    print("有%d個引數"%len(params))
    print("第二個引數是:",params[1])

    
>>> test(1,2,3,4,5,6,7,8)
有8個引數
第二個引數是: 2
>>> test("小甲魚",123,3.14)
有3個引數
第二個引數是: 123

Python就是把標誌為收集引數的引數們打包成一個元組。不過,需要注意的是:如果在收集引數的後面還需要指定其它引數,在呼叫函式的時候就應該使用關鍵字引數來指定,否則Python就都會把你的實參都列入收集引數的範疇。舉個例子:

>>> def test(*params,extra):
    print("收集引數是",params)
    print("位置引數是",extra)

    
>>> test(1,2,3,4,5,6,7,8)
Traceback (most recent call last):
  File "<pyshell#38>", line 1, in <module>
    test(1,2,3,4,5,6,7,8)
TypeError: test() missing 1 required keyword-only argument: 'extra'
>>> test(1,2,3,4,5,6,7,extra=8)
收集引數是 (1, 2, 3, 4, 5, 6, 7)
位置引數是 8

建議在引數中帶有收集引數是,可以將其它引數設定為預設引數,這樣不容易出錯:

>>> test(1,2,3,4,5,6,7,extra=8)
收集引數是 (1, 2, 3, 4, 5, 6, 7)
位置引數是 8
>>> def test(*params,extra=8):
    print("收集引數是",params)
    print("位置引數是",extra)

    
>>> test(1,2,3,4,5,6,7,8)
收集引數是 (1, 2, 3, 4, 5, 6, 7, 8)
位置引數是 8
>>> test(1,2,3,4,5,6,7)
收集引數是 (1, 2, 3, 4, 5, 6, 7)
位置引數是 8

星號(*)其實既可以”打包“,也可以“解包“。舉個例子,假如你需要將一個列表a傳入test引數的收集引數 *params中,那麼呼叫test(a)時便會出錯,此時,你需要在a前面加上個星號(*)表示引數需要"解包"後才能使用:

>>> def test(*params):
    print("有%d個引數"%len(params))
    print("第二個引數是:",params[1])

    
>>> a=[1,2,3,4,5,6,7,8]
>>> test(a)
有1個引數
Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    test(a)
  File "<pyshell#45>", line 3, in test
    print("第二個引數是:",params[1])
IndexError: tuple index out of range
>>> test(*a)
有8個引數
第二個引數是: 2

Python還有一種收集的形式,就是用兩個星號(**)表示。跟前面的介紹不同,兩個星號的收集參數列示為將引數們打包成字典的形式。後面講解。

 

*******************************

六、課時18課後習題及答案

*******************************

相關文章