【循序渐进学Python】6.Python中的函数
1. 創(chuàng)建函數(shù)
一個(gè)函數(shù)代表一個(gè)行為并且返回一個(gè)結(jié)果(包括None),在Python中使用def關(guān)鍵字來(lái)定義一個(gè)函數(shù),如下:
def hello(name):print 'hello,' + name + '!'?接下來(lái)調(diào)用函數(shù),并查看其返回值:
# output: # hello,gy! # None print hello('gy')可以看到hello函數(shù)首先打印了:Hello,gy!,然后我們又將其返回值也打印出來(lái),在這里因?yàn)闆](méi)有返回具體的值,所以返回了None。
?
下面我們可以定義一個(gè)用于計(jì)算斐波那契數(shù)列的函數(shù),接收計(jì)算的位數(shù)(參數(shù)),返回計(jì)算的結(jié)果(返回值),如下:
1 def fibs(num): 2 result = [0,1] 3 for i in range(num - 2): 4 result.append(result[-2] + result[-1]) 5 return result 6 7 # output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] 8 print fibs(10)?
2. 文檔字符串
文檔字符串指的是在函數(shù)開(kāi)頭寫(xiě)下該函數(shù)的說(shuō)明字符串,該字符串會(huì)作為函數(shù)的一部分進(jìn)行存儲(chǔ)??梢酝ㄟ^(guò)調(diào)用__doc__屬性來(lái)查看:
1 def fibs(num): 2 "根據(jù)指位數(shù)來(lái)計(jì)算斐波那契數(shù)列" 3 result = [0,1] 4 for i in range(num - 2): 5 result.append(result[-2] + result[-1]) 6 return result 7 8 # 輸出:根據(jù)指位數(shù)來(lái)計(jì)算斐波那契數(shù)列 9 print fibs.__doc__?
3. 參數(shù)
函數(shù)使用參數(shù)來(lái)傳遞信息,而參數(shù)類(lèi)型又基本分為兩大類(lèi)型:可變類(lèi)型參考和不可變類(lèi)型參數(shù)。
?
3.1 不可變類(lèi)型參數(shù)
不可變類(lèi)型(字符串、數(shù)字和元組等)是不可變的,即無(wú)法修改,只能使用新的值來(lái)覆蓋。使用不可變類(lèi)型作為函數(shù)的參數(shù)時(shí):在函數(shù)內(nèi)為參數(shù)賦值不會(huì)改變其外部變量的值,如下:
1 # 字符串是不可變的 2 def try_to_change(n): 3 n = 'Gumby' 4 5 name = 'Sunshine' 6 7 # 嘗試改變參數(shù)的值 8 try_to_change(name) 9 10 # output: Sunshine(函數(shù)內(nèi)部的改變對(duì)其沒(méi)有影響) 11 print name?
3.2 可變類(lèi)型參數(shù)
可變類(lèi)型參數(shù)(列表等)指的是:使用可變的數(shù)據(jù)結(jié)構(gòu)來(lái)作為函數(shù)的參數(shù)使用。在函數(shù)內(nèi)部修改可變類(lèi)型參數(shù)的值時(shí),會(huì)同時(shí)改變其外部變量的值(因?yàn)樗鼈円玫钠鋵?shí)是同一個(gè)對(duì)象),如下所示:
1 # 列表是可變的 2 def try_to_change2(n): 3 n[0] = 'Sunshine' 4 5 person = ['Gumby','Bob'] 6 # 嘗試改變參數(shù)的值 7 try_to_change2(person) 8 9 # output: ['Sunshine', 'Bob'] 10 # 函數(shù)內(nèi)部的改變會(huì)作用于外部的變量 11 print person?
如果想避免上面的情況可以對(duì)需要作為可變類(lèi)型的參數(shù)的對(duì)象復(fù)制一個(gè)副本,這里是列表可以通過(guò)對(duì)其進(jìn)行切片來(lái)返回一個(gè)新的副本,如下:
1 # 將可變的數(shù)據(jù)結(jié)構(gòu)(列表)用作參數(shù) 2 def try_to_change2(n): 3 n[0] = 'Sunshine' 4 5 person = ['Gumby','Bob'] 6 n = person[:] # 通過(guò)切片返回新的副本 7 try_to_change2(n) 8 print person # ['Gumby', 'Bob'] 9 print n # ['Sunshine', 'Bob'] 10 print n is person # False?
3.3 關(guān)鍵字參數(shù)和默認(rèn)值
在我們之前使用參數(shù)的形式是:位置參數(shù),即調(diào)用該函數(shù)給其傳值時(shí),是根據(jù)輸入的值的先后順序來(lái)給參數(shù)一一賦值 的。不過(guò)有時(shí)候如果我們需要定義的函數(shù)有大量的參數(shù)時(shí),傳值時(shí)只是于依賴(lài)于順序的話(huà)是比較容易出錯(cuò)的。同時(shí)如果部分參數(shù)在不多數(shù)情況下值都是一樣的,每次 調(diào)用都需要重新賦值也比較麻煩。針對(duì)于這種情況Python為我們提供了兩個(gè)語(yǔ)法糖:即關(guān)鍵字參數(shù)和默認(rèn)值。(PS:C#4.0新增的兩個(gè)特性:具名參數(shù)和可選參數(shù),和Python的這兩個(gè)語(yǔ)法糖很類(lèi)似,感興趣的同學(xué)可以參考這里:《Effective C#》讀書(shū)筆記——條目10:使用可選參數(shù)減少方法重載的數(shù)量<C#語(yǔ)言習(xí)慣>)。
使用關(guān)鍵字參數(shù)不需要對(duì)函數(shù)進(jìn)行任何修改,只需要在調(diào)用函數(shù)時(shí)顯示為參數(shù)賦值即可(不依賴(lài)特定順序),如下:
1 def hello(gretting,name): 2 print "%s,%s!" % (gretting,name) 3 4 # output: hello,world! 5 hello(name='world',gretting='hello')?
可以看到雖然調(diào)用時(shí)代碼變多了,但是每個(gè)參數(shù)的含義一目了然。不過(guò)有時(shí)候我們的函數(shù)有些參數(shù)在大部分情況下使用同樣的值,有時(shí)候也需要改變,這時(shí)候使用默認(rèn)值,可以很好的解決這種問(wèn)題,如下:
1 def hello(gretting = 'hello',name='world'): 2 print "%s,%s!" % (gretting,name) 3 4 hello() # hello,world! 5 hello(name = 'Sunshine') # hello,Sunshine! 6 hello('Greetings') # Greetings,world!?可以看到,如果沒(méi)有給任何值的話(huà),函數(shù)自動(dòng)使用默認(rèn)值,也可以通過(guò)關(guān)鍵字參數(shù)指定部分值,其他的依然使用默認(rèn)參數(shù),這為我們的方法調(diào)用提供了很大的靈活性。
?
3.4 使用任意參數(shù)列表
前面介紹的參數(shù)的個(gè)數(shù)基本都是固定的,有時(shí)候可以接收任意多的參數(shù)也是很有必要的,這時(shí)候可以使用Python為我們提供的語(yǔ)法糖(*號(hào))來(lái)實(shí)現(xiàn):
1 def print_params(number,*params): 2 print number 3 print params 4 5 # output: 6 # 6 7 # (1, 2, 3, 4, 5, 6) 8 print_params(6,1,2,3,4,5,6) 9 10 # output: 11 # 0 12 # () 13 print_params(0)?
我們可以看到參數(shù)前的*號(hào)將所有的值放置到一個(gè)元組中(可以理解為將其他的參數(shù)收集起來(lái))。如果沒(méi)有為*號(hào)后的參數(shù)賦值則其值為一個(gè)空的元組。不過(guò)使用一個(gè)*號(hào)這樣的語(yǔ)法不能處理關(guān)鍵字參數(shù),如下:
1 def print_params(*params): 2 print params 3 4 # TypeError: print_params() got an unexpected keyword argument 'params' 5 print_params(params = (1,2,3))?
解決的辦法很簡(jiǎn)單,使用**來(lái)修飾參數(shù)即可,如下所示:
1 # -- coding: utf-8 -- 2 def print_params(**params): 3 print params 4 print type(params) 5 6 # output: {'params': (1, 2, 3)} 7 # output: <type 'dict'> 8 print_params(params = (1,2,3))?可以看到使用**修飾的參數(shù)本質(zhì)上其實(shí)是一個(gè)字典類(lèi)型??梢酝ㄟ^(guò)這個(gè)字典來(lái)收集參數(shù)。
?
3.5 解包參數(shù)列表
除了通過(guò)才定義函數(shù)的參數(shù)(形參)前添加*或者**來(lái)收集參數(shù),我們還可以在調(diào)用函數(shù)時(shí)在實(shí)參前調(diào)解這兩個(gè)操作符,它們表示其對(duì)應(yīng)的逆過(guò)程。如下所示:
1 def add(x,y): 2 print x + y 3 4 params = (1,2) 5 6 # output: 3 7 add(*params)?
通過(guò)使用*操作符我們將params參數(shù)分割了add函數(shù)所需的兩個(gè)參數(shù),同樣我們也可以使用**操作符來(lái)分割字典對(duì)象:
1 def hello(greeting,name): 2 print '%s,%s' %(greeting,name) 3 4 params = {'greeting':'hello','name':'world'} 5 6 # output: hello,world 7 # 這里使用*操作符也是可以的 8 hello(**params)?
參考資料&進(jìn)一步閱讀
Python基礎(chǔ)教程(第二版)
Python入門(mén)教程——深入函數(shù)定義
轉(zhuǎn)載于:https://www.cnblogs.com/IPrograming/p/Python_function.html
總結(jié)
以上是生活随笔為你收集整理的【循序渐进学Python】6.Python中的函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C:\Users\xx\.xxxxxx\
- 下一篇: correct ways to defi