1. 程式人生 > >Python 高級變量類型 --- 函數的進階

Python 高級變量類型 --- 函數的進階

tex 我們 傳遞函數 自身 特點 tro 記憶 註意 1-1

目標

  • 函數參數和返回值的作用
  • 函數的返回值 進階
  • 函數的參數 進階
  • 遞歸函數

01,函數參數和返回值的作用

函數根據 有沒有參數 以及 有沒有返回值 ,可以 相互組合 , 一共4種組合
1,無參數,無返回值
2,無參數,有返回值
3,有參數,無返回值
4,有參數,有返回值

    ![](https://images2018.cnblogs.com/blog/1306461/201808/1306461-20180817100230702-1077210530.png)

定義函數時是否接收參數,或者是否返回結果, 是根據 實際的功能需求 來決定的
1,如果函數 內部處理的數據不確定 ,就可以將外界的數據參數傳遞函數內部
2,如果希望一個函數 執行完成後,向外界匯報執行結果

,就可以增加函數返回值

02,函數的返回值 進階

  • 在程序開發中,有時候,會希望 一個函數執行結束後,告訴調用這一個結果, 以便調用者針對具體的結果做後續的處理
  • 返回值 是函數 完成工作後,最後 給調用者的 一個結果
  • 在函數中使用return 關鍵值可以返回結果
  • 調用函數一方,可以 使用變量接收 函數的返回結果

問題 :一個函數執行後能否返回多個結果?

示例 -- 溫度和濕度測量

  • 假設要開發一個函數能夠同時返回當前的溫度和濕度
  • 先完成返回溫度 的功能如下:

    def measuring():
        """測量溫度和濕度"""
    
        print("測量開始 ----")
        temp = 23
        humidity = 35
        print("測量結束 ----")
    
        # 元組 - 可以包含多個數據,因此可以使用元組讓函數一次返回多個值
        # 如果函數返回的類型是元組,小括號可以省略
        # return (temp, humidity)
        return temp, humidity
    
    
    # 元組
    result = measuring()
    print(result)
    
    # 需要單獨的處理溫度或者濕度
    print(result[0])
    print(result[1])
    
    # 如果函數返回的類型是元組,同時希望單獨處理元組中的元素
    # 可以使用多個變量,一次接收函數的返回值
    # 註意,使用多個變量接收結果時,變量的個數應該和元組中元素的個數保持一致
    t_temp, t_humidity = measuring()
    
    print("測量的溫度為: %.2f" % t_temp)
    print("測量的濕度為: %.2f" % t_humidity)
    
    
    # 結果呈現
    測量開始 ----
    測量結束 ----
    (23, 35)
    23
    35
    測量開始 ----
    測量結束 ----
    測量的溫度為: 23.00
    測量的濕度為: 35.00

交換兩個數字


    
    # 定義變量
    a = 100
    b = 50
    
    # 解法一:使用其他變量
    c = a
    a = b
    b = c
    
    # 解法二:不使用其他變量
    a = a + b
    b = a - b
    a = a - b
    
    # 解法三: python專有
    a, b = (b, a)
    
    # 提示:等號右邊是一個元組,只是把小括號省略了
    a, b = b, a
    
    print("a = %d" % a)
    print("b = %d" % b)
    
    
    # 結果呈現
    a = 50
    b = 100

03,函數的參數 進階

3.1 不可變和可變的參數

問題1:在函數內部,針對參數使用 賦值語句, 會不會影響調用函數時傳遞的 實參變量? -- 不會!

  • 無論傳遞的參數是 可變 還是 不可變
    • 只要 針對參數 使用 賦值語句 ,會在 函數內部 修改 局部變量的引用,不會影響到 外部變量的引用

    def demo(num, num_list):
    
        # 在函數內部,針對參數使用賦值語句,不會修改到外部的實參變量
        num = 100
        num_list = [4, 5, 6]
    
        print("函數內部代碼 num = %d" % num)
        print("函數內部代碼 num_list = %s" % (num_list))
    
    gl_num = 66
    gl_num_list = [1, 2, 3]
    
    demo(gl_num, gl_num_list)
    
    print("函數外部代碼 gl_num = %d" % gl_num)
    print("函數外部代碼 gl_num_list = %s" % (gl_num_list))
    
    # 結果呈現
    函數內部代碼 num = 100
    函數內部代碼 num_list = [4, 5, 6]
    函數外部代碼 gl_num = 66
    函數外部代碼 gl_num_list = [1, 2, 3]

問題2: 如果傳遞的參數是 可變類型,在函數內部,使用 方法 修改了數據的內容, 同樣會影響到外部的數據


    def demo(num_list):
    
        # 使用方法修改列表的內容
        num_list.append(6)
    
        print("函數內部代碼 %s" % num_list)
    
    gl_num_list = [1, 2, 3]
    
    demo(gl_num_list)
    
    print("函數外部代碼 %s" % gl_num_list)
    
    # 結果呈現
    函數內部代碼 [1, 2, 3, 6]
    函數外部代碼 [1, 2, 3, 6]

+=

  • python中,列表變量詞用+=本質上是在執行列表變量的extend方法,不會修改變量的引用

    def demo(num, num_list):
    
        # num = num + num
        num += num
    
        # 列表變量使用 += 不會做相加在賦值的操作!
        # num_list = num_list + num_list
        # 本質上是在調用列表的 extend 方法
        num_list += num_list
        # num_list.extend(num_list)
    
        print("函數內部代碼 num = %d" % num)
        print("函數內部代碼 num_list = %s" % (num_list))
    
    gl_num = 66
    gl_num_list = [1, 2, 3]
    
    demo(gl_num, gl_num_list)
    
    print("函數外部代碼 gl_num = %d" % gl_num)
    print("函數外部代碼 gl_num_list = %s" % (gl_num_list))
    
    # 結果呈現
    函數內部代碼 num = 132
    函數內部代碼 num_list = [1, 2, 3, 1, 2, 3]
    函數外部代碼 gl_num = 66
    函數外部代碼 gl_num_list = [1, 2, 3, 1, 2, 3]

3.2 缺省參數

  • 定義函數時,可以給 某個參數 指定一個 默認值 ,具有默認值的參數就叫做缺省參數
  • 調用函數時,如果沒有傳入 缺省參數 的值,則在函數內部使用定義函數時指定的 參數默認值
  • 函數缺省參數, 將常見的值設置為參數的缺省值,從而 簡化函數的調用
  • 例如:對列表排序的方法

    gl_list = [6, 3, 9]
    
    # 默認安裝升序排序
    gl_list.sort()
    
    print("升序排序 %s" % gl_list)
    
    # 如果需要降序排序,需要執行 reverse 參數
    # reverse 參數就是一個缺省值,默認值為:reverse=False
    gl_list.sort(reverse=True)
    
    print("降序排序 %s" % gl_list)
    
    # 結果呈現
    升序排序 [3, 6, 9]
    降序排序 [9, 6, 3]

指定函數缺省參數

  • 在參數後使用賦值語句,可以指定參數的缺省值

    def print_info(name, gender=True):
        """
    
        :param name: 班上同學的姓名
        :param gender: True 男生,False 女生
        :return:
        """
    
        gender_text = "男生"
    
        if not gender:
            gender_text = "女生"
    
        print("%s 是 %s" % (name, gender_text))
    
    # 草帽海賊船上男生居多
    # 提示:在指定缺省參數的默認值時,應該使用最常見的值作為默認值
    print_info("蒙奇·D·路飛")
    print_info("羅羅諾亞·索隆")
    print_info("娜美", False)
    print_info("烏索普")
    print_info("文斯莫克·山治")
    print_info("托尼托尼·喬巴")
    print_info("妮可·羅賓", False)
    print_info("弗蘭奇")
    print_info("布魯克")
    print_info("甚平")
    
    # 結果呈現
    蒙奇·D·路飛 是 男生
    羅羅諾亞·索隆 是 男生
    娜美 是 女生
    烏索普 是 男生
    文斯莫克·山治 是 男生
    托尼托尼·喬巴 是 男生
    妮可·羅賓 是 女生
    弗蘭奇 是 男生
    布魯克 是 男生
    甚平 是 男生

提示
1,缺省參數,需要使用 最常見的值 作為默認值!
2,如果一個參數的值 不能確定 ,則不應該設置默認值,具體的數值在調用函數時,由外界傳遞!

缺省參數的註意事項

1) 缺省參數的定義位置

  • 必須保證 帶有默認值的缺省參數 在參數列表末尾
  • 所以,以下定義是錯誤的!
def print_info(name, gender=True, title)

2)調用帶有多個缺省參數的函數

  • 調用函數時,如果有 多個缺省參數,需要指定參數名,這樣解釋器才能夠知道參數的對應關系
    def print_info(name,title="", gender=True):
        """
    
        :param name: 班上同學的姓名
        :param gender: True 男生,False 女生
        :return:
        """
    
        gender_text = "男生"
    
        if not gender:
            gender_text = "女生"
    
        print("[%s] %s 是 %s" % (title, name, gender_text))
    
    # 草帽海賊船上男生居多
    # 提示:在指定缺省參數的默認值時,應該使用最常見的值作為默認值
    print_info("蒙奇·D·路飛")
    print_info("羅羅諾亞·索隆")
    print_info("娜美", gender=False)
    
    # 結果呈現
    [] 蒙奇·D·路飛 是 男生
    [] 羅羅諾亞·索隆 是 男生
    [] 娜美 是 女生

3.3 多值參數

定義支持多值參數的函數

  • 有時可能需要 一個函數 能夠處理的參數 個數 是不確定的,這個時候,就可能使用 多值參數
  • python 中有 兩種 多值參數
    • 參數名前增加 一個* 可以接收 元組
    • 參數名前增加 兩個* 可以接收 字典
  • 一般在給多值參數命名時,習慣 使用一下兩個名字
    • *args -- 存放 元組 參數,前面有一個 *
    • **kwargs -- 存放 字典 參數,前面有兩個**
  • argsarguments 的縮寫,有變量的含義
  • kwkeyword 的縮寫, kwargs 可以記憶 鍵值對參數

    def demo(num, *nums, **person):
    
        print(num)
        print(nums)
        print(person)
    
    demo(1)
    
    # 結果呈現
    1
    ()
    {}

    def demo(num, *nums, **person):
    
        print(num)
        print(nums)
        print(person)
    
    demo(1, 2, 3, 4, 5, 6, name = "蒙奇·D·路飛", age = 18)
    
    # 結果呈現
    1
    (2, 3, 4, 5, 6)
    {‘name‘: ‘蒙奇·D·路飛‘, ‘age‘: 18}

提示多值參數 的應用會經常出現在網絡上開發的框架中,知道多值參數,有利於我們能夠讀懂大牛的代碼

多值參數 -- 計算任意多個數字的和

需求

1,定義一個函數 sum_numbers,可以接收 任意多個參數
2,功能要求:將傳遞的 所有數字累加 並且返回累加結果


    def sum_numbers(*args):
    
        num = 0
    
        print(args)
    
        # 循環遍歷
        for i in args:
            num += i
    
        return num
    
    result = sum_numbers(1, 2, 3, 4, 5)
    
    print(result)
    
    # 結果呈現
    (1, 2, 3, 4, 5)
    15

元組和字典的拆包

  • 在調用帶有多值參數的函數時,如果希望:
    • 將一個 元組變量,直接傳遞給 args
    • 將一個 字典變量,直接傳遞給 kwargs
  • 就可以使用 拆包 ,簡化參數的傳遞, 拆包 的方式是:
    • 元組變量前,增加一個*
    • 字典變量前,增加兩個**

    def demo(*agrs, **kwargs):
    
        print(agrs)
        print(kwargs)
    
    
    # 元組變量 、字典變量
    gl_nums = (1, 2, 3)
    gl_dict = {"name" : "蒙奇·D·路飛", "age" : 18}
    
    # 拆包語法,簡化元組變量和字典變量的傳遞
    demo(*gl_nums, **gl_dict)
    demo(1, 2, 3, name = "蒙奇·D·路飛", age = 18)
    
    # 結果呈現
    (1, 2, 3)
    {‘name‘: ‘蒙奇·D·路飛‘, ‘age‘: 18}
    (1, 2, 3)
    {‘name‘: ‘蒙奇·D·路飛‘, ‘age‘: 18}

04,函數的遞歸

函數調用自身的 編程技巧 稱為 遞歸

4.1 遞歸函數的特點

特點

  • 一個函數 內部 調用自己
    • 函數內部可以調用其它函數,當然在函數內部也可以調用自己

代碼特點

1,函數內部的 代碼 是相同的,只是針對 參數 不同,處理的結果不同
2,當 參數滿足一個條件 時,函數不再執行
- 這個非常重要 ,通常被稱為遞歸的出口,否則 會出現死循環!


    def sum_number(num):
        print(num)
    
        # 遞歸的出口,當參數滿足某個條件時,不再執行函數
        if num == 1:
            return
    
        # 函數自己調自己
        sum_number(num - 1)
    
    sum_number(3)
    
    # 結果呈現
    3
    2
    1
    ![](https://images2018.cnblogs.com/blog/1306461/201808/1306461-20180817162534671-1466867391.png)

4.2 遞歸案例 -- 計算數字累加

需求

1,定義一個函數 sum_numbers
2,能夠接收一個 num 的整數參數
3,計算 1 + 2 + ...num 的結果


    def sum_number(num):
    
        # 遞歸的出口,當參數滿足某個條件時,不再執行函數
        if num == 1:
            return 1
    
        # 數字累加 num + (1 ...num -1)
        # 假設 sum_number 能夠正確的處理 1 ...num -1
        temp = sum_number(num - 1)
    
        # 兩個數字相加
        return num + temp
    
    result = sum_number(100)
    
    print(result)
    
    # 結果呈現
    5050
    ![](https://images2018.cnblogs.com/blog/1306461/201808/1306461-20180817164432041-364913179.png)

提示:遞歸是一個 編程技巧,初次接觸遞歸會感覺有些吃力!在處理 不確定的循環體條件時 ,格外的有用,例如: 遍歷整個文件目錄的結構

Python 高級變量類型 --- 函數的進階