函數(shù)是指組織好的,可重復(fù)使用的,用來實現(xiàn)單一或相關(guān)聯(lián)功能的代碼段,它能夠提高應(yīng)用的模塊化和代碼的重復(fù)利用率。
Python提供了很多內(nèi)建函數(shù),如print()。除此之外,我們還可以自己創(chuàng)建函數(shù),也就是自定義函數(shù)。接下來,看一段代碼:
print("*")
print("**")
print("****")
上述代碼中,使用多個print()函數(shù)輸出了一個三角形。如果需要在一個程序的不同位置輸出這個圖形,那么每次都使用print()函數(shù)輸出的做法是不可取的。為了提高編寫的效率以及代碼的重用性,我們可以把具有獨立功能的代碼塊組織成一個小模塊,這就是函數(shù)。
在Python中,你可以定義一個自己想要功能的函數(shù),自定義函數(shù)的語法格式如下所示
def 函數(shù)名(參數(shù)列表):
“函數(shù)_文檔字符串”
函數(shù)體
return 表達(dá)式
基于上述格式,下面對函數(shù)定義的規(guī)則進(jìn)行說明:
(1)函數(shù)代碼塊以def開頭,后面緊跟的是函數(shù)名和圓括號()。
(2)函數(shù)名的命名規(guī)則跟變量的命名規(guī)則是一樣的,即只能是字母、數(shù)字和下劃線的任何組合,但是不能以數(shù)字開頭,并且不能跟關(guān)鍵字重名。
(3)函數(shù)的參數(shù)必須放在圓括號中。
(4)函數(shù)的第1行語句可以選擇性地使用文檔字符串來存放函數(shù)說明。
(5)函數(shù)內(nèi)容以冒號起始,并且縮進(jìn)。
(6) return表達(dá)式結(jié)束函數(shù),選擇性地返回一個值給調(diào)用方。不帶表達(dá)式的retu相當(dāng)于返回None。
定義了函數(shù)之后,就相當(dāng)于有了一段具有特定功能的代碼,要想讓這些代碼能夠執(zhí)行,需要調(diào)用函數(shù)。調(diào)用函數(shù)的方式很簡單,通過“函數(shù)名()”即可完成調(diào)用。
# 定義一個函數(shù),能夠完成打印信息功能
def print_info():
print("-"*20)
print("人生苦短,我用python!")
print("-"*20)
# 調(diào)用函數(shù)
print_info()
在介紹函數(shù)的參數(shù)之前,我們先來解決一個問題?,F(xiàn)在要求定義一個函數(shù),這個函數(shù)用于計
算兩個數(shù)的和,并把計算的結(jié)果打印出來。把上述要求轉(zhuǎn)換為代碼,示例代碼如下:
def add():
c = 11 + 22
print(c)
以上函數(shù)的功能是計算11和22的和。此時,無論調(diào)用這個函數(shù)多少次,得到的結(jié)果永遠(yuǎn)都是一樣的,而且只能計算固定的兩個數(shù)字的和,使得這個函數(shù)的局限性很大。
為了能讓定義的函數(shù)更加通用,即計算任意兩個數(shù)字的和,可以在定義函數(shù)的時候添加兩個參數(shù),讓兩個參數(shù)來接收傳遞給函數(shù)的值。接下來,通過一個案例來演示函數(shù)是如何傳遞參數(shù)的。
def add(a, b):
c = a + b
print(c)
上面案例中,定義了能接收兩個參數(shù)的函數(shù)。其中,a為第一個參數(shù),用于接收函數(shù)傳遞的第1個數(shù)值;b為第二個參數(shù),接收的是函數(shù)的第2個數(shù)值。這時,如果想調(diào)用add函數(shù),則需要給函數(shù)的參數(shù)傳遞兩個數(shù)值,如下所示為完整代碼:
def add(a, b):
c = a + b
print(c)
# 調(diào)用帶有參數(shù)的函數(shù)時,需要在小括號中傳遞數(shù)據(jù)。
add(35, 25)
上面代碼運行結(jié)果為:
50
需要注意的是,如果函數(shù)定義了多個參數(shù),那么在調(diào)用函數(shù)的時候,傳輸?shù)臄?shù)據(jù)要和定義的參數(shù)一一對應(yīng)。上面的案例中a=35,b=25,c=50。
定義函數(shù)時,可以給函數(shù)的參數(shù)設(shè)置默認(rèn)值,這個參數(shù)就被稱為默認(rèn)參數(shù)。當(dāng)調(diào)用參數(shù)的時候,由于貓人參數(shù)在定義時已經(jīng)被賦值,所以可以直接忽略,而其它參數(shù)是必須要傳入值的。
如果默認(rèn)參數(shù)沒有傳入值,則直接使用默認(rèn)的值;如果默認(rèn)參數(shù)傳入了值,則使用傳入的新值替代。
下面我們通過一個案例來介紹。
def print_info(name, age=35):
# 打印任何傳入的字符串
print("Name:", name)
print("age:", age)
# 調(diào)用print_info(name="miki")
print_info(name="miki")
print_info(name="miki", age=9)
運行結(jié)果為:
Name: miki
age: 35
Name: miki
age: 9
在上面案例,第1~4行代碼定義了帶有兩個參數(shù)的print_info函數(shù)。其中,name參數(shù)沒有設(shè)置默認(rèn)值,age作為默認(rèn)參數(shù)已經(jīng)設(shè)置了默認(rèn)值。在第6行調(diào)用print_into函數(shù)時,由于只傳入了name參數(shù)的值,所以程序會使用age參數(shù)的默認(rèn)值;在第7行調(diào)用print_info函數(shù)時,同時傳入了name和age兩個參數(shù)的值,所以程序會使用傳給age參數(shù)的新值。
需要注意的是,帶有默認(rèn)值的參數(shù)一定要位于參數(shù)列表的最后面,否則程序會報錯。例如,給 print_info函數(shù)添加一個參數(shù)sex,放在參數(shù)列表的最后面,則報錯信息如下圖所示:
通常在定義一個函數(shù)時,若希望函數(shù)能夠處理的參數(shù)個數(shù)比當(dāng)初定義的參數(shù)個數(shù)多,此時可以在函數(shù)中使用不定長參數(shù)。其基本的語法格式如下:
def 函數(shù)名([forml_args,] *args, **kwargs):
"函數(shù)_文檔字符串"
函數(shù)體
return 表達(dá)式
在上述格式中,函數(shù)共有3個參數(shù)。其中,formal_args為形參(也就是前面所用的參數(shù),如(a,b),*args和** kwargs為不定長參數(shù)。當(dāng)調(diào)用函數(shù)的時候,函數(shù)傳入的參數(shù)個數(shù)會優(yōu)先匹配formal_args參數(shù)的個數(shù)。如果傳入的參數(shù)個數(shù)和formal_args參數(shù)的個數(shù)相同,不定長參數(shù)會返回空的元組或字典;如果傳入?yún)?shù)的個數(shù)比formal_args參數(shù)的個數(shù)多,可以分為如下兩種情況:
(1)如果傳入的參數(shù)沒有指定名稱,那么*args會以元組的形式存放這些多余的參數(shù)
(2)如果傳入的參數(shù)指定了名稱,如m=1,那么* kwargs會以字典的形式存放這些被命名的參數(shù),如{m:1}。
為了大家更好地理解,先通過一個簡單的案例進(jìn)行演示,具體如下所示。
def test(a, b, *args):
print(a)
print(b)
print(args)
test(11, 12
運行結(jié)果如下:
11
12
()
在上面案例中,第1~4行代碼定義了帶有多個參數(shù)的test函數(shù)。其中,args為不定長參數(shù)。當(dāng)在第5行中調(diào)用test函數(shù)時,由于只傳入11和122這兩個數(shù),所以這兩個數(shù)會從左向右依次匹配test函數(shù)定義時的參數(shù)a和b,此時,args參數(shù)沒有接收到數(shù)據(jù),所以為一個空元組。
如果在調(diào)用test函數(shù)時,傳入多個參數(shù)(這里指的是大于2個參數(shù))情況又是什么樣的呢?
下面看一段實例代碼:
def test(a, b, *args):
print(a)
print(b)
print(args)
test(11, 12, 13, 14, 15, 16, 17, 18
運行結(jié)果如下:
11
12
(13, 14, 15, 16, 17, 18)
如果在參數(shù)列表的末尾使用* kwargs參數(shù),示例代碼如下
def test(a, b, *args, **kwargs):
print(a)
print(b)
print(args)
print(kwargs)
test(11, 12, 13, 14, 15, 16, 17, 18
運行結(jié)果:
11
12
(13, 14, 15, 16, 17, 18)
{}
從兩次運行的結(jié)果可以看出,如果在調(diào)用test函數(shù)時傳入多個數(shù)值,那么這些數(shù)值會從左向
右依次匹配函數(shù)test定義時的參數(shù)。如果跟formal_args參數(shù)的個數(shù)匹配完,還有多余的參數(shù),則這些多余的參數(shù)會組成一個元組,和不定長參數(shù)args進(jìn)行匹配。此時,kwargs參數(shù)沒有接受到數(shù)據(jù),所以為一個空字典。
在調(diào)用函數(shù)時,什么情況下傳入的數(shù)據(jù)會匹配參數(shù)kwargs呢?看下面案例:
def test(a, b, *args, **kwargs):
print(a)
print(b)
print(args)
print(kwargs)
test(11, 12, 13, 14, 15, 16, 17, 18, m=22, n=33)
運行結(jié)果為:
11
12
(13, 14, 15, 16, 17, 18)
{'m': 22, 'n': 33}
從上述運行結(jié)果可以看出,如果參數(shù)是以鍵值對的形式傳入的,則使用** kwargs參數(shù)來接收。
所謂“返回值”,就是程序中的函數(shù)完成一件事情后,最后給調(diào)用者的結(jié)果。比如,定義一
個函數(shù)來獲取室內(nèi)的溫度,一旦調(diào)用這個函數(shù),函數(shù)就會把拿到的溫度值返回給調(diào)用者,這個溫暖值就是函數(shù)的返回值。在Python中,函數(shù)的返回值是使用 return語句來完成的。接下來,看一段示例代碼。
def add(a, b):
c = a + b
return
或者
def add(a, b):
return a + b
上面的代碼中,函數(shù)add中包含了return語句,意味著這有個函數(shù)的返回值,其返回值就是a和b相加的結(jié)果。
根據(jù)有沒有參數(shù)和返回值,函數(shù)大概可以分為以下四種類型:
(1)函數(shù)無參數(shù),無返回值。
(2)函數(shù)無參數(shù),有返回值。
(3)函數(shù)有參數(shù),無返回值。
(4)函數(shù)有采參數(shù),有返回值。
下面我們分別介紹。
1)無參數(shù)、無返回值的參數(shù)
無參數(shù)、無返回值的函數(shù),既不能接受參數(shù),也沒有返回值。
接下來,我們通過打印提示的函數(shù)來演示這類函數(shù)的使用。
def print_menu():
print("-"*20)
print(" xx涮鍋 點菜系統(tǒng)")
print(" 1. 羊肉涮鍋")
print(" 2. 牛肉涮鍋")
print(" 3. 豬肉涮鍋")
print("-" * 20)
print_menu(
運行結(jié)果為:
2)無參數(shù)、有返回值的函數(shù)
此類函數(shù)不能接收參數(shù),但是可以返回某個數(shù)據(jù),一般情況下,采集數(shù)據(jù)時會用此類函數(shù)。接下來,我們通過一個示例來演示,如下所示:
# 獲取溫度def get_temperature():
# 這里是溫度獲取的一些處理過程
# 為了簡單起見,先模擬返回一個數(shù)據(jù)
return 24
temperture = get_temperature()
print('當(dāng)前的溫度為:', temperture
運行結(jié)果為:
當(dāng)前的溫度為: 24
3)有參數(shù)、無返回值的函數(shù)
在實際開發(fā)中,有參數(shù)、無返回值的函數(shù)用的極少,這是因為函數(shù)作為功能模塊,既然傳入了參數(shù),絕大多數(shù)情況是希望使用返回值的。這里,大家對有參數(shù)、無返回值的函數(shù)有所了解即可,實例代碼如下:
def test(number_one, number_two):
result = number_one + number_two
print('計算結(jié)果為: %d'%result
4)有參數(shù)、有返回值得函數(shù)
此類函數(shù)不能接收參數(shù),但是可以返回某個數(shù)據(jù),一般情況下,采集數(shù)據(jù)時會用此類函數(shù)。
接下來,我們通過一個示例來演示。
# 計算1~number的累積和
def calculate(nuber):
result = 0
i = 1
while i <= nuber:
result = result +i;
i +=1
return result
result = calculate(100)
print('1~100的累積和為:', result
運行結(jié)果為: