第五章:函數

第一節:關於函數

函數的基本概念

【函數】,是將一段代碼進行封裝和命名,這個名稱對應的就是一個函數,調用該名稱即等於執行該代碼段;
【函數參數】,是調用者給函數傳入的值;
【返回值】,是函數返回給調用者的結果;

函數的定義和調用

本例定義一個函數talk(),通過調用talk(),即打印四句話

# 定義一個函數
def talk():
#  縮進的部分是函數體,函數體的範圍叫做這個函數的作用域
    print("善惡終有報")
    print("天道有輪迴")
    print("不信擡頭看")
    print("蒼天饒過誰")
#  調用該函數,注意此處的縮進
talk()

執行結果:
在這裏插入圖片描述

函數的參數和返回值

# 加入兩個參數,分別由兩人說兩句
def talk(man1,man2):
#  縮進的部分是函數體,函數體的範圍叫做這個函數的作用域
    print("%s說:善惡終有報" % man1)
    print("%s說:天道有輪迴" % man1)
    print("%s說:不信擡頭看" % man2)
    print("%s說:蒼天饒過誰" % man2)

    return "你要我說什麼?"

#  調用該函數,輸入參數
talk("孔子","老子")

# 直接打印此函數,看返回給函數的返回值是什麼
print(talk("孔子","老子"))

執行結果:
在這裏插入圖片描述

函數的作用

將重複使用的代碼片段進行封裝,以提高代碼的易用性和複用率;

第二節:函數參數

位置參數 & 關鍵字參數

【位置參數】,在函數的參數定義中僅僅給出參數名稱的參數;在下面的函數定義中,man1man2是位置參數;
【關鍵字參數】,在函數的參數定義中以key=default_value形式給出的參數,下面的函數中placedate是關鍵字參數,因爲都是以鍵值對形式進行定義的;
【注意】在函數定義時,通常把關鍵字參數定義在位置參數的後面,位置參數是要按順序傳,而且必須傳

例如

# 加入位置參數和關鍵字參數
def talk(man1,man2,place="書塾",date='10月16日'):
	#使用位置參數
    print("%s說:善惡終有報" % man1)
    print("%s說:天道有輪迴" % man1)
    print("%s說:不信擡頭看" % man2)
    print("%s說:蒼天饒過誰" % man2)

    #使用關鍵字參數
    print("——%s 於 %s"%(date,place))

#  調用該函數,輸入位置參數
talk("孔子","老子")

#調用該函數,輸入關鍵字參數
talk("孔子","老子",date="11月11日",place="廁所")

執行結果:
在這裏插入圖片描述

位置參數的傳參原則:位置參數一個也不能少、順序也不能亂,對位置參數傳參時如果少傳或者亂序傳入,會引起TypeError,而不能正常執行

比如上面的例子:

def talk(man1,man2,place="書塾",date='10月16日'):
    print("%s說:善惡終有報" % man1)
    print("%s說:天道有輪迴" % man1)
    print("%s說:不信擡頭看" % man2)
    print("%s說:蒼天饒過誰" % man2)

    print("——%s 於 %s"%(date,place))

#  調用該函數,但位置參數只輸少了
talk("孔子")

執行結果:
在這裏插入圖片描述

關鍵字參數傳參原則:
關鍵字參數是選傳的,而不是必傳的,當不傳時傳用默認值。可以以key=value形式進行傳參,此時傳參的順序是可以隨意的。也可以省去key,直接傳value,但此時傳參的順序就必須與函數參數定義的順序保持一致

不定長參數

  • 不定長位置參數*args

使用不定長位置參數,用於表示任意多個位置參數;
Python標準庫中習慣使用*args來命名不定長位置參數,不定長位置參數的類型爲元組

以下用一個例子說明不定長位置參數,使用*someone,表示不確定有多少人點贊,注意*args要放在關鍵字參數的前面、位置參數的後面。

def talk(man1,man2,*someone,place="書塾",date='10月16日',):
    print("%s說:善惡終有報" % man1)
    print("%s說:天道有輪迴" % man1)
    print("%s說:不信擡頭看" % man2)
    print("%s說:蒼天饒過誰" % man2)

    print("——%s 於 %s"%(date,place))
    #這裏因爲有*someone,無論有多少點贊者都照單全收,而且是用元組表示
    print(someone,"表示點贊!")

#  調用該函數,輸入位置參數和不定長位置參數
talk("孔子","老子","孟子","李白","杜甫",)

執行結果:
在這裏插入圖片描述

  • 不定長關鍵字參數**kwargs

使用不定長關鍵字參數,用於表示任意多個關鍵字參數;
Python標準庫中習慣使用**kwargs來命名不定長位置參數,不定長關鍵字參數的類型爲字典;並且要安排在最後

例如:

def talk(man1,man2,*args,place="書塾",date='10月16日',**kwargs):
    print("%s說:善惡終有報" % man1)
    print("%s說:天道有輪迴" % man1)
    print("%s說:不信擡頭看" % man2)
    print("%s說:蒼天饒過誰" % man2)

    print("——%s 於 %s"%(date,place))
    print(args,"表示點贊!")
    print('評論:',kwargs)

#  調用該函數,輸入各種參數,注意不定長關鍵字參數一定要在最後
talk(
    "孔子","老子",                               # 位置參數
    "孟子","李白","杜甫",                        # 不定長位置參數
    date="9月12日",place="銀河中心城",           # 關鍵字參數
    bill = '說得真好!',Tom = '人之初,性本善。'   # 不定長關鍵字參數
)

執行結果:
在這裏插入圖片描述

參數順序總結:位置參數-不定長位置參數-關鍵字參數-不定長關鍵字參數

第三節:函數返回值

  • 多個返回值

Python語言中的函數返回值可以是一個,也可以是多個,這是Python相比其他語言的簡便和靈活之處;
接收者可以用一個結果來接收多個返回值,此時該結果的類型是元組
接收者也可以用多個變量來接收多個結果,此時變量的個數和返回值的個數應相等;

例如:

def date(man):
    print('%s,下午我們去逛街吧!'%man)
    #一次返回多個返回值
    return '好的!',666,'下午見!'




if __name__ == '__main__':
    
    # 用一個結果來接收多個返回,類型是元組
    ret = date('店小二')
    print('對方說:',ret)
    
    # 用多個變量來接收多個結果
    r1 , r2 , r3 = date('店小二')
    print('對方說:',r1)
    print('對方說:',r2)
    print('對方說:',r3)

執行結果:
在這裏插入圖片描述

第四節:變量作用域

局部變量&全局變量

變量根據其作用域不同,可以分爲局部變量全局變量
【局部變量】是隻在函數內起作用的變量、在函數外部無法訪問;局部變量隨函數執行而創建,隨函數的結束而消亡,其生命週期只在函數執行中;
【全局變量】是定義在函數外的變量,函數內外都可以訪問;函數內訪問全局變量要使用global關鍵字;全局變量的生命週期與程序本身是相同的(除非使用del xxx進行刪除);

形式參數&實際參數

函數方法定義中的參數名稱,我們稱之爲形式參數;形式參數的名稱是任意的,它是接收實際參數的一個符號,在函數未被調用時,它是沒有值的;
在調用函數時傳入的參數的【值】,稱爲實際參數
【形參】與【實參】的關係,即【定義】與【傳參】,亦即【符號】與【實值】;
形參將實參接入函數內部,是一個局部變量;
基本類型的函數傳參是拷貝式的,也就是說,無論實參在函數內部被重新賦值多少次,對外界的“本體”都是沒有影響的;
對象類型的函數傳參是引用式的,函數內的改變,會影響函數外

例:

def raiseSalary(salary):
    # 將參數增大
    salary *= 2
    print("領導:馬上給你加薪到%d"%(salary))

if __name__ == '__main__':
    
    # 加薪以前的薪水
    salary = 2000
    # 執行加薪函數,實參爲2000
    raiseSalary(salary)
    #實參salary到函數內部變成了拷貝,拷貝版只是一個局部變量,函數結束以後消失於無形,對實參不產生任何實際影響
    print("嘿嘿:薪水其實是%d"%(salary))

執行結果:
在這裏插入圖片描述

總結:我們發現函數外的那個值爲2000的salary,在函數內被修改爲4000,但函數執行結束後,其值依然爲2000。這是因爲,當raiseSalary(salary)時,只是拷貝了salary的值而已,因此無論函數如何修改拷貝形成的局部變量,對全局變量salary都是沒有任何影響的!如果想要實際訪問和修改全局變量,函數內要加global關鍵字進行聲明.

例如:

def raiseSalary():
    #明使用全局變量salary
    global salary
    salary *= 2
    print("領導:馬上給你加薪到%d"%(salary))

if __name__ == '__main__':

    # 加薪以前的薪水
    salary = 2000
    # 執行加薪函數,函數使用了全局變量,對salary進行了修改
    raiseSalary()
    print("嘿嘿:薪水其實是%d"%(salary))

執行結果:
在這裏插入圖片描述

第五節:函數的封裝

封裝ASCII字符生成器

第六節:複用模塊

第七節:迭代器與生成器

第八節:斐波那契數列生成器

第九節:偏函數

第十節:repr__與__str

第十一節:回調函數

第十二節:實例方法、類方法、靜態方法

第十三節:lambda表達式

第十四節:高階函數

第十五節:列表去重求和

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章