Python函數(shù)
函數(shù)是組織好的,可重復(fù)使用的,用來(lái)實(shí)現(xiàn)單一,或相關(guān)聯(lián)功能的代碼段。
函數(shù)能提高應(yīng)用的模塊性,和代碼的重復(fù)利用率。
1.Python函數(shù)定義
def functionname(parameters):
? ?"函數(shù)_文檔字符串"
? ?function_suite
? ?return [expression]
2.對(duì)象創(chuàng)建
在 python 中,類型屬于對(duì)象,變量是沒有類型的:
a=[1,2,3] #賦值后這個(gè)對(duì)象就已經(jīng)創(chuàng)建好了
a="Runoob"
以上代碼中,[1,2,3] 是 List 類型,"Runoob" 是 String 類型,而變量 a 是沒有類型,她僅僅是一個(gè)對(duì)象的引用(一個(gè)指針),可以是 List 類型對(duì)象,也可以指向 String 類型對(duì)象。
3.可更改對(duì)象和不可更改對(duì)象
在 python 中,strings,tuples, 和 numbers 是不可更改(重新賦值后,原值不再存在)的對(duì)象,而 list,dict等則是可以修改(重新賦值后,原來(lái)的值依舊存在,依舊可以獲取到)的對(duì)象。
·? ? ? ?不可變類型:變量賦值 a=5 后再賦值 a=10,這里實(shí)際是新生成一個(gè) int 值對(duì)象 10,再讓 a 指向它,而 5 被丟棄,不是改變a的值,相當(dāng)于新生成了a。
·? ? ? ?可變類型:變量賦值 la=[1,2,3,4] 后再賦值 la[2]=5 則是將 list la 的第三個(gè)元素值更改,本身la沒有動(dòng),只是其內(nèi)部的一部分值被修改了。
4.可更改對(duì)象和不可更改對(duì)象的參數(shù)傳遞
python函數(shù)的參數(shù)傳遞:
不可變類型:類似 c++的值傳遞,如 整數(shù)、字符串、元組。如fun(a),傳遞的只是a的值,沒有影響a對(duì)象本身。比如在fun(a)內(nèi)部修改 a 的值,只是修改另一個(gè)復(fù)制的對(duì)象,不會(huì)影響 a本身。
def ChangeInt(a):
a = 10
b = 2
ChangeInt(b)
print(b)? ?#結(jié)果是 2
int2對(duì)象指向變量b,而調(diào)用changeInt函數(shù)時(shí),變量a就是變量b,此時(shí)的變量a和變量b都對(duì)應(yīng)int 2對(duì)象,但是在之后a被重新賦值為10,此時(shí)變量a指向?qū)ο骾nt 10,產(chǎn)生了一個(gè)新的int型對(duì)象,而變量b所指向的對(duì)象不變。
?
可變類型:類似 c++的引用傳遞,如 列表,字典。如 fun(la),則是將 la真正的傳過(guò)去,修改后fun外部的la也會(huì)受影響
python 中一切都是對(duì)象,嚴(yán)格意義我們不能說(shuō)值傳遞還是引用傳遞,我們應(yīng)該說(shuō)傳不可變對(duì)象和傳可變對(duì)象。
def changeme( mylist):?
mylist.append([1,2,3,4]);? #"修改傳入的列表"
? ? print("函數(shù)內(nèi)取值: ", mylist)
? ? return
?
# 調(diào)用changeme函數(shù)
mylist = [10,20,30];
changeme(mylist);
print("函數(shù)外取值: ", mylist)
因?yàn)樯厦娴拇a傳遞的是可變對(duì)象,因此在函數(shù)內(nèi)取值和函數(shù)外取值都是同樣的結(jié)果。
5.調(diào)用函數(shù)時(shí)的參數(shù)使用
1)必備參數(shù)
必須與函數(shù)聲明時(shí)一致的順序來(lái)傳遞參數(shù)。
2)關(guān)鍵字參數(shù)
傳參數(shù)時(shí)可與函數(shù)聲明的順序不一樣,因?yàn)镻ython解釋器可以用參數(shù)名來(lái)匹配參數(shù)值。
3)缺省參數(shù)
傳入?yún)?shù)時(shí)未給參數(shù)賦值,則保持默認(rèn)值。
#可寫函數(shù)說(shuō)明
def printinfo( name, age=35):
print("Name: ", name);? #"打印任何傳入的字符串"
? ? print("Age ", age);
? ? return;
?
#調(diào)用printinfo函數(shù)
printinfo(age=50,name="miki");
printinfo(name="miki");
這里第二句的age沒有輸入值,則輸出默認(rèn)值35。
4)不定長(zhǎng)參數(shù)(也就是包含非必備參數(shù)的參數(shù)定義)
當(dāng)不確定會(huì)傳入?yún)?shù)的個(gè)數(shù)時(shí),可以對(duì)可以不輸入的參數(shù)名前面加“*”號(hào),按順序輸入時(shí)進(jìn)行對(duì)應(yīng)即可。
def printinfo( arg1,*vartuple):
print("輸出: ",arg1)? #"打印任何傳入的參數(shù)"
? ? for var in vartuple:
? ? ? print var
? ? return;
?
# 調(diào)用printinfo函數(shù)
printinfo(10);
printinfo(70,60,50);
5.匿名函數(shù)(使用lambda創(chuàng)建)
python 使用 lambda來(lái)創(chuàng)建匿名函數(shù)。
lambda只是一個(gè)表達(dá)式,函數(shù)體比def簡(jiǎn)單很多。?
lambda的主體是一個(gè)表達(dá)式,而不是一個(gè)代碼塊。僅僅能在lambda表達(dá)式中封裝有限的邏輯進(jìn)去。
lambda函數(shù)擁有自己的命名空間,且不能訪問(wèn)自有參數(shù)列表之外或全局命名空間里的參數(shù)(只能訪問(wèn)自己的命名空間里的參數(shù))。
雖然lambda函數(shù)看起來(lái)只能寫一行,卻不等同于C或C++的內(nèi)聯(lián)函數(shù),后者的目的是調(diào)用小函數(shù)時(shí)不占用棧內(nèi)存從而增加運(yùn)行效率。
# 用一個(gè)語(yǔ)句來(lái)定義一個(gè)Sum函數(shù)
sum = lambda arg1, arg2: arg1+ arg2;
? ??
# 調(diào)用sum函數(shù)
print("相加后的值為 : ", sum(10,20))
print("相加后的值為 : ", sum(20,20))
6.變量作用域
1)全局變量
定義在所有函數(shù)外則為全局變量,可在所有代碼中使用。
當(dāng)需要在函數(shù)內(nèi)定義全局變量時(shí),必須用global語(yǔ)句。
2)局部變量
定義在函數(shù)內(nèi)則為局部變量,只能在相應(yīng)的代碼塊內(nèi)使用。
total = 0; # 這是一個(gè)全局變量
# 可寫函數(shù)說(shuō)明
def sum( arg1, arg2):? ?#返回2個(gè)參數(shù)的和."
? ? total = arg1 + arg2; # total在這里是局部變量.
? ? print("函數(shù)內(nèi)是局部變量 : ", total)
? ? return(total);
?
#調(diào)用sum函數(shù)
sum( 10, 20);
print("函數(shù)外是全局變量 : ", total)
在上面的例子中,在函數(shù)內(nèi)部,total是局部變量,而在外部total是全局變量,局部變量的改變不會(huì)改變?nèi)肿兞康闹?,因此第一個(gè)打印結(jié)果是30,而第二個(gè)是0。