1. 程式人生 > >pthon_函式的定義與呼叫

pthon_函式的定義與呼叫

1、函式概念

函式是組織好的,可重複使用的,用來實現單一,或相關聯功能的程式碼段。函式能提高應用模組性,和程式碼的重複利用率。如print(),range()函式,但你也可以自己建立函式

2、函式定義

定義函式的規則:

a、函式程式碼塊以def關鍵詞開頭,後接函式識別符號名稱和圓括號()

b、任何傳入引數和自變數必須放在圓括號中間。圓括號之間可以用於定義引數

c、函式的第一行語句可以選擇性的使用文件字串—用於存放函式說明

d、函式內容以冒號起始,並且縮排

e、return[表示式]結束函式,選擇性的返回一個值給呼叫方,不帶表示式的return相當於返回none

3、案例:

定義一個函式Max_num(),用來比較兩個數字的大小,然後將數值大的數字返回

def Max_num (a,b) :

if a > b:

return a

elif a < b :

return b

else:

return a

#函式呼叫

result=Max_num(10,20)

print(result)

案例2:

def printme (str) : #列印傳入的字串

print str

return

#呼叫函式

printme(“今天是星晴六”)

printme(“今天是星期日”)

4、引數傳遞:

在python中,型別屬於物件,變數是沒有型別的

a=[1,2,3]

a="happy"

[1,2,3]是list型別,“happy”是string型別。變數a是沒有型別的,它僅僅是一個物件的引用(一個指標),可以是list型別物件,也可以只想string型別物件

5、可更改(mutable)與不可更改(immutable)物件

在python中。string,tuples和numbers是不可更改的物件,而list,dict等則是可以修改的物件

a、不可變型別:變數賦值a=5後在賦值a=10,實際是新生成一個int值物件10,在讓a指向它,5被丟棄,不是改變a的值,是新生成了a

b、可變型別:變數賦值la=[1,2,3,4],後在賦值la[2]=5,則是將list la的第三個元素值更改,本身la沒有動,只是內部的一部分值被修改了

python函式的引數傳遞

a、不可變型別:類似c++的值傳遞,如整數、字串、元組。如fun(a),傳遞的只是a的值,沒有影響a物件本身,比如在fun(a)內部修改a的值,只是修改另一個複製的物件,不會影響a本身

b、可變型別:類似c++的引用傳遞,如列表,字典。如fun(la),則是將la真正的傳過去,修改後fun外部的la也會受影響

python中一切都是物件,嚴格意義我們不能說值傳遞還是引用傳遞,我們應該說傳不可變物件和傳可變物件

python傳不可變物件例項:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

def ChangeInt( a ):

    a = 10

    b = 2

ChangeInt(b) print b # 結果是 2

例項中有int物件2,指向它的變數是b,在傳遞changeInt函式時,按傳值的方式複製了變數b,a和b都指向了同一個int物件,在a=10時,則新生成一個int值物件10,並讓a指向它

傳可變物件例項:

def changeme (mylist) :

mylist.append([1,2,3,4])

print(mylist)

return

mylist = [10,20,30]

changeme(mylist)

print(mylist)

6、引數

以下是呼叫函式時可使用的正式引數型別

必備引數

關鍵字引數

預設引數

不定長引數

(1)必備引數:

須以正確的順序傳入函式,呼叫時的數量必須和宣告時的一樣

呼叫printme()函式,必須傳入一個引數,不然會出現語法錯誤:如下所示

#可寫函式說明

def printme( str ): #"列印任何傳入的字串"

print str; return;

printme(); #呼叫printme函式

輸出結果:

Traceback (most recent call last):

File "test.py", line 11, in <module> printme();

TypeError: printme() takes exactly 1 argument (0 given)

(2)關鍵字引數

關鍵字引數和函式呼叫關係緊密,函式呼叫使用關鍵字引數來確定傳入的引數值

使用關鍵字引數允許函式呼叫時引數的順序與宣告時不一致,因為pyhon直譯器能夠用引數名匹配引數值。

舉例:在函式printme()呼叫使用引數名

#可寫函式說明

def printme( str ):    #"列印任何傳入的字串"

print str; return;      #呼叫printme函式

printme( str = "My string");

舉例2:

#可寫函式說明

def printinfo( name, age ):  #"列印任何傳入的字串"

print("Name: ", name);

print("Age ", age);

return;

#呼叫printinfo函式

printinfo( age=50, name="miki" );

(3)預設引數

呼叫函式時,預設引數的值如果沒有傳入,則被認為是預設值,下面的例子會預設列印預設的age,如果age沒有被傳入

def printinfo( name, age = 35 ): 

 #"列印任何傳入的字串"

print ("Name: ", name);

print ("Age ", age);

return;

#呼叫printinfo函式

printinfo( age=50, name="miki" );

printinfo( name="miki" );

(4)不定長引數

需要一個函式能處理比當初宣告時更多的引數,這些引數就叫做不定長引數,和上述2種引數不同,宣告時不會命名。舉例:

加了星號(*)的變數名會存放所有為命名的變數引數

def printinfo (age1,*vartuple):

print("輸出:") #列印任何傳入的引數

print(age1)

for var in vartuple:

print(var)

return;

#呼叫printinfo函式

printinfo(10);

printinfor(70,60,50);

輸出結果:

輸出:10

輸出:70,60,50

(5)匿名函式

python使用lambda來建立匿名函式

a、lambda只是一個表示式,函式體比def簡單很多

b、lambda的主體是一個表示式,而不是一個程式碼塊,僅僅能在lambda表示式中封裝有限的邏輯進去

c、lambda函式擁有自己的名稱空間,且不能訪問自有引數列表之外或全域性名稱空間裡的引數

d、雖然lambda函式看起來只能寫一行,卻不等同與c++或c的行內函數,後者的目的是呼叫小函式時不佔用棧記憶體從而增加執行效率

語法:

lambda [arg1,arg2,.....argn]:expression

舉例:

sum = lambda arg1, arg2: arg1 + arg2;

# 呼叫sum函式

print("相加後的值為 : ", sum(10, 20))

print("相加後的值為 : ", sum(20, 20))

結果:

相加後的值為 : 30

相加後的值為 : 40

(6)return語句

return語句[表示式]退出函式,選擇性地向呼叫方返回一個表示式,不帶引數值的return語句返回none。

案例1:

def sum (arg1,arg2) :

total=arg1 + arg2

print("函式和",total)

return total;

#呼叫sum函式

total = sum(10,20);

執行結果:

函式和:30

(7)變數作用域

一個程式的所有的變數並不是在哪個位置都可以訪問的。訪問許可權決定於這個變數是在哪裡賦值的。變數的作用域決定了在哪一部分程式你可以訪問哪個特定的變數名稱。兩種最基本的變數作用域如下:

全域性變數

區域性變數

全域性變數和區域性變數:

定義在函式內部的變數擁有一個區域性作用域,定義在函式外的擁有全域性作用域

區域性變數只能在其被宣告的函式內部訪問,而全域性變數可以在整個程式範圍內訪問。呼叫函式時,所有在函式內宣告的變數名稱都被加入到作用域中。

案例1:

total=0 #這是一個全域性變數

def sum( arg1,arg2):

total = arg1 + arg2

print("函式內是區域性變數:",total)

return total ;

#呼叫sum函式

sum( 10,20 ) ;

print("函式外是全域性變數:",total)

執行結果:

函式內是區域性變數:30

函式外是全域性變數:0