Python之函數詳解

                                               Python之函數詳解

一、函數的概述

     簡單地說,函數就是個黑匣子,它接收輸入(參數),然後執行特定任務以完成特定功能,最後生成輸出(返回值)。其中,輸入(參數)和輸出(返回值)都是可選的,也就是說,可以有也可以沒有函數就是執行特定任務以完成特定功能的一段代碼。可以在程序中將某段代碼定義成函數,並指定函數名及接收的輸入(參數),這樣,就可以在程序的其它地方通過函數名多次調用並執行該段代碼了每次調用並執行後,都會根據接收的輸入(參數)執行特定任務以完成特定功能從而生成相應的輸出(返回值)Python語言已經定義了很多內置函數。我們可以在程序中通過函數名直接調用這些內置函數。例如:當我們調用內置函數id()時,輸入(參數)是任意的對象,完成的特定功能是獲取輸入(參數)的唯一標識,輸出(返回值)是輸入(參數)的唯一標識。


二、爲什麼需要函數

1.複用代碼  如果在程序中需要多次完成某個特定的功能,我們無需把這個特定功能的相關代碼在多個地方編寫多次,完全可以把這個特定功能的相關代碼定義成函數,然後在多個地方調用該函數,每次調用都會把函數對應的相關代碼執行一遍。

2.隱藏實現細節  函數就是個黑匣子,將實現細節隱藏起來了。很多時候我們無需關注函數的實現細節,只需關注其接收的輸入(參數)及生成的輸出(返回值)就可以了。

3.提高可維護性  把完成某段特定功能的代碼定義爲函數後,如果需要對這段代碼進行修改,只需要在一個地方進行修改,提高了程序的可維護性。否則,你需要找到這段代碼的多個不同地方,每個地方都要進行同樣的修改,費事費力還容易出錯。

4.提高可讀性、便於調試每個函數都對應一段完成特定功能的代碼,提高了程序的可讀性,也便於程序調試。


三、函數的定義和調用

1、定義函數定義

函數的語法格式

def 函數名([形式參數1,形式參數2,形式參數n]):

    函數體

其中,def是 Python定義的關鍵字。


關於函數名的說明

a) 每個函數都有一個函數名,用於函數的調用。

b) 函數名屬於標識符,因此,必須遵守標識符的命名規則,推薦遵守標識符的命名規範。


關於形式參數的說明

a) 形式參數簡稱形參

b) 形參用於在調用函數時接收輸入,也就是接收傳遞的實際參數(簡稱實參)

c) 形參用中括號括起來,表示形參時可選的,也就是說,可以定義也可以不定義。

d) 形參的本質是變量,其作用域(起作用的範圍)僅限於函數體


關於函數體的說明

a) 函數體是用於執行特定任務以完成特定功能的主體代碼

b) 函數體對應的代碼塊必須縮進。

c) 如果函數需要有輸出(返回值),可以在函數體內通過語句 return xxx進行返回,同時結束函數體的執行。

如果函數不需要有輸出(返回值),可以在函數體內通過語句 return直接結束函數體的執行,或者讓函數體正常執行結束,其實,函數在這兩種情況下都是有返回值的,其返回值都是None。

d) 函數體在調用函數時纔會被執行,因此,定義函數不會改變程序的執行流程。


2、函數調用

調用函數時,每個實參都被用於初始化相應的形參。所有形參都被初始化之後,函數體對應的代碼塊被執行。程序的執行流會跳轉到定義函數的函數體內,執行函數體對應的代碼塊,執行完函數體後再跳回到調用函數的地方,繼續執行下一條語句。


def test(arg1,arg2):
    if arg1 and arg2:
        return arg1 and arg2
    elif arg1 or arg2:
        return arg1 or arg2
    else:
        return False
        
print(test('hi',1)) # 1
print(test(1,[])) # 1
print(test('',[])) # False


四、函數調用之位置實參

調用函數時,可以根據每個形參在所有形參中的位置傳遞對應位置的實參,從而用每個實參初始化對應位置的形參,這樣的實參稱爲位置實參。

def test1(arg1,arg2,arg3):
    print('a = ', arg1, 'b = ', arg2, 'c =', arg3)
# 實參位置不同是,初始化的形參值也不同,返回的值也會有變化
test1(1,2,3) # a =  1 b =  2 c = 3
test1(3,2,1) # a =  3 b =  2 c = 1


五、函數調用之關鍵字實參

調用函數時,傳遞的實參的形式可以爲: 形參名=實參值,從而用指定的實參值初始化指定名稱的形參這樣的實參稱爲關鍵字實參。

def test2(a,b,c):
    print('a = ', a, 'b = ', b, 'c = ', c)
# 調用函數時,可以指定實參值初始化指定名稱的形參
test2(a = 1, b = 2, c = 3) # a =  1 b =  2 c =  3
test2(a = 3, b = 1, c = 2) # a =  3 b =  1 c =  2


六、函數調用之實參傳遞

對於傳遞不可變類型的實參和可變類型的實參,傳入可變類型的實參值會受到函數體內運算的影響。不可變類型的實參則不受影響。

def test3(arg1,arg2):
    arg1 * 10
    arg2.append(4)
    print(arg1,arg2)
i = 10
L = [1,2,3]
test3(i,L) # 10 [1, 2, 3, 4]

print('i的值', i, 'L的值', L) # i的值 10 L的值 [1, 2, 3, 4]


七、函數的定義之多個返回值

如果需要在調用函數後有多個返回值,可以在定義函數時在函數體內使用 return語句返回由多個返回值組成的元組。

def test4(arg1):
    even = []
    odd = []
    for i in arg1:
        if i % 2:
            even.append(i)
        else:
           odd.append(i)
    # return 定義返回兩個列表的值
    return even,odd
L = list(range(1,11))

print(test4(L)) # ([1, 3, 5, 7, 9], [2, 4, 6, 8, 10])


八、函數定定義之帶默認值的形參

定義函數時,可以給形參設置默認值,這樣,調用函數時如果不傳遞對應的實參,就會使用設置的默認值初始化形參。給形參設置默認值的語法格式爲: 形參=默認值 給形參設置默認值之後,可以簡化函數的調用,只有與默認值不符的形參才需要傳遞額外的實參。

def test5(a,b = 5):
    print('a = ', a, 'b = ', b)
    
test5(10) # a =  10 b =  5 未傳入b的實參,使用默認值b = 5


九、函數定義之使用*定義關鍵字形參

定義函數時,可以在所有形參的某個位置添加一個*,這樣,*後面的所有形參都被定義爲只能接收關鍵字實參的關鍵字形參。

def test6(a,b,*,c,d):
    print('a = ', a, 'b = ', b, 'c = ', c, 'd = ', d)
# 調用函數時,必須傳入c = xx d = xx的關鍵字參數
test6(1,2,c = 3,d = 4) # a =  1 b =  2 c =  3 d =  4
#test6(1,2,3,4)  test6() takes 2 positional arguments but 4 were given


十、函數定義之使用*定義個數可變的位置形參

定義函數時,可能無法事先確定傳遞的位置實參的個數,在這種情況下,可以在形參前添加一個*,將形參定義爲個數可變的位置形參,從而可以接收0個或任意多個位置實參。這些位置實參會將個數可變的位置形參初始化爲一個元組。

def test7(arg1,*arg2):
    print('arg1 = ', arg1, '*arg2 = ', arg2)
    
# 傳入實參時可以傳入多個參數,arg1接收第一個參數,*arg2接收剩餘的參數
test7(1,2,3,4) # arg1 =  1 *arg2 =  (2, 3, 4)


十一、函數調用之使用*將序列中的每個元素轉換爲位置實參

調用函數時,可以在序列前面添加一個*,從而將序列中的每個元素都轉換爲一個單獨的位置實參。

def test8(a,b,c):
    print('a = ', a, 'b = ', b, 'c = ', c)
    
L = [1,2,3]
# 正常調用,需要依次傳遞L的索引作爲實參,然後初始化形參
test8(L[0],L[1],L[2]) # a =  1 b =  2 c =  3
# 調用時使用*,將序列中的每一個元素轉換成單獨的位置實參
test8(*L) # a =  1 b =  2 c =  3


十二、函數定義之使用**定義個數可變的關鍵字形參

定義函數時,可能無法事先確定傳遞的關鍵字實參的個數,在這種情況下,可以在形參前添加兩個*將形參定義爲個數可變的關鍵字形參,從而可以接收0個或任意多個關鍵字實參。這些關鍵字實參會將個數可變的關鍵字形參初始化爲一個字典。

def test9(**kwargs):
    print(kwargs)
    
#傳入多個關鍵字實參,初始華**kwargs,以字典的形式返回值
test9(a = 1, b = 2, c = 3) # {'a': 1, 'b': 2, 'c': 3}

# 因爲位置形參必須要在關鍵字形參之前,所以個數可變的位置參數必須在個數可變的關鍵字參數之前
def test10(*args,**kwargs):
    print(args,kwargs)

test10(1,2,3,a = 11, b = 12) # (1, 2, 3) {'a': 11, 'b': 12}


十三、函數調用值使用**將字典的每個鍵值對都轉換爲關鍵字參數

調用函數時,可以在字典前添加兩個**,從而將字典中的每個鍵值對都轉換爲一個單獨的關鍵字實參。

def test11(a,b,c):
    print('a = ',a, 'b = ', b, 'c = ', c)
    
d = {'a':1,'b':2,'c':3}
test11(**d) # a =  1 b =  2 c =  3
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章