首頁 > 軟體

Python基礎學習之函數和程式碼複用詳解

2022-08-18 18:03:38

Python函數和程式碼複用

什麼是函數:

  函數是一段具有特定功能的,可重用的語句組,通過函數名來表示和呼叫。經過定義,一組語句等於一個函數,在需要使用這組語句的地方,直接呼叫函數名稱即可。因此,函數包括兩部分:函數的定義和函數的呼叫。

為什麼要使用函數:

  • 程式碼複用
  • 影藏實現細節
  • 提高可維護性
  • 提高可讀性便於偵錯
  • 降低程式設計難度

一、函數的定義

語法格式:

def  函數名 ([參數列]):
    函數體
    return 返回值列表 

例:

# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

def calc(a, b):  # 函數定義
    c = a + b
    return c

二、函數的呼叫

函數的定義也叫函數“宣告”,定義後的函數不能直接執行,需要經過“呼叫”才能得到執行。

語法格式:

函數名(實際賦值參數列)

# 函數建立
def calc(a, b):  # 函數定義
    c = a + b
    return c

'''
函數呼叫:
函數名(實際參數列)'''
d = calc(10, 20)  # 函數呼叫
print(d)  # 30

三、函數的引數傳遞

函數的引數在定義時可以指定預設值,當函數被呼叫時,如果沒人傳入對應的引數時,則使用函數定義時的預設值替代。

語法格式

def  函數名(非可選參數列,可選參數列=預設值):
    函數體
    return 返回值列表 

1.形式引數與實際引數

  • 函數定義處的引數稱為形式引數
  • 函數呼叫處的引數稱為實際引數

2.位置傳參與關鍵字傳參

# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

# 函數的引數傳遞
'''
1.位置傳參 根據形參對應的位置進行引數傳遞
2.關鍵字實參 根據形參名稱進行引數傳遞
'''

def calc(a, b):  # a b 為函數定義當處的形式引數
    c = a + b
    return c

calc(10, 20)  # 10 20 為函數呼叫處的實際引數

# 位置實參
print(calc(10, 20))  

# =左側的變數的名稱稱為關鍵字引數
print(calc(b=10, a=20))  

3.可變物件與不可變物件的引數傳遞

在函數呼叫過程中,進行參的傳遞:

  • 如果是不可變物件,函數體的修改不會影響實參的值
  • 若果是可變物件,函數體的改變會影響到實參的值
# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

'''
在函數呼叫過程中,進行參的傳遞:
如果是不可變物件,函數體的修改不會影響實參的值
若果是可變物件,函數體的改變會影響到實參的值
'''

def fun(arg1, arg2):
    print('arg1=', arg1)
    print('arg2=', arg2)
    arg1 = 100  # arg1 的修改為100不會影響n1的值
    arg2.append(200)  # are2 的修改會影響到n2的值
    print('arg1=', arg1)  # 100
    print('arg2=', arg2)  # [10, 20, 200]
    return arg1, arg2

a = 10
b = [10, 20]
print('a', a)  # 10
print('b', b)  # [10, 20]
x = fun(a, b)  # 位置傳參 arg1,arg2時是函數定義處的形參,n1,n2是函數呼叫處的實參, 實參和形參的名稱可以不一致
print(a)  # 10
print(b)  # [10, 20, 200]
print(x)  # (100, [10, 20, 200])

4.個數可變的位置、關鍵字引數

個數可變的位置引數: *arges

引數定義時,可能無法事先確定傳遞的位置實參的個數,使用可變的位置引數

個數可變的關鍵字形參:**kwargs

引數定義時,可能無法事先確定傳遞的位置實參的個數,使用可變的位置引數

在一個函數的定義過程中,既有個數可變的 *arges位置形參,又有個數可變的**kwargs關鍵字形參,要求把位置形參放在前面

# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

# 個數可變的位置引數 *arges
# 引數定義時,可能無法事先確定傳遞的位置時參的個數,使用可變的位置引數

def fun(*args):  # 函數定義時,可變的位置引數
    print(args)  # 返回值為元組
    # print(args[0])  返回元組的第1個物件

fun(10)  # (10, )
fun(10, 20)  # (10, 20)
fun(11, 22, 33)  # (11, 22, 33)

# 個數可變的關鍵字形參
# 引數定義時,可能無法事先確定傳遞的位置是參的個數,使用可變的位置引數
def fun(**kwargs):
    print(kwargs)  # 返回值是 字典

fun(a=10)  # {'a': 10}
fun(a=10, b=20, c=30)  # {'a': 10, 'b': 20, 'c': 30}

'''
def fun2(*args,*a)
    pass
以上程式報錯,個數可變的的位置引數值能有一個
def fun2(**kwargs)
    pass
個數可變的關鍵字引數也只能有一個
'''

# 在一個函數的定義過程中,既有個數可變的位置形參,又有個數可變的關鍵字形參,要求把位置形參放在前面
def fun(*args, **kwargs):
    pass

5.函數引數總結(一)

# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

def fun(a, b, c):  # a,b,c在函數定義處,所以是形式引數
    print('a=', a)
    print('b=', b)
    print('c=', c)

# 函數呼叫
fun(10, 20, 30)  # 函數呼叫時的引數傳遞,稱為位置傳參
lst = [11, 22, 33]
fun(*lst)  # 函數呼叫,將列表中的每個元素都轉換為位置實參傳遞

fun(a=100, b=200, c=300)  # 函數呼叫,所以是關鍵字實參
dic = {'a': 111, 'b': 222, 'c': 333}
print(fun(**dic))  # 函數呼叫時,將字典中的鍵值對都轉換為關鍵字實參傳遞

6.函數引數總結(二)

def fun(a, b=10):  # a是形式引數

    print('b=', b)

def fun2(*args):  # 個數可變的位置形參
    print(args)

def fun3(**kwargs):  # 個數可變的關鍵字形參
    print(kwargs)

# 函數呼叫
fun(10)
fun(10, 20)
fun2(10, 20, 30)
fun3(a=10, b=20)
print('--------------------------')

def fun4(a, b, *, c, d):  # 需求 c,d 只能採用關鍵字實參傳遞
    print('a=', a)
    print('b=', b)
    print('c=', c)
    print('d=', d)

# fun4(10, 20, 30, 40)   # 位置實參傳遞
fun4(a=10, b=20, c=30, d=40)  # 關鍵字實參傳遞
print('--------------------------')
fun4(10, 20, c=30, d=40)  # 前面兩個進行位置實參傳遞,後面兩個採用關鍵字實參傳遞

''' 函數定義時的形參順序問題'''

def fun5(a, b, *, c, d, **kwargs):
    pass

def fun6(*args, **kwargs):
    pass

def fun7(a, b=10, *args, **kwargs):
    pass

四、函數的返回值

  return語句用來結束函數並將程式返回到函數呼叫的位置繼續執行。return語句可以出現在函數中的任何部分,同時可以將0個、1個或多個函數運算的結果返回給函數被呼叫處的變數。

函數的返回值

  • 如果沒有返回值(函數執行完畢後,不需要給呼叫處提供資料),return可以省略不寫
  • 若果返回值為1個,直接返回型別原型別
  • 如果返回值為個,返回結果為元組
# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

'''
函數的返回值:
(1)如果沒有返回值(函數執行完畢後,不需要給呼叫處提供資料),return可以省略不寫
(2)若果返回值為1個,直接返回型別原型別
(2)如果返回值為多個,返回結果為元組
'''

def fun(lst):
    odd = []
    even = []
    for i in lst:
        if i % 2:
            odd.append(i)
        else:
            even.append(i)
    print(odd, even)
    return odd, even  # 沒有返回值,可以省略  如果返回值為多個,返回結果為元組

lst1 = [12, 34, 45, 57, 67, 78, 89]
print(lst1)

# 函數呼叫
print(type(fun(lst1)))
'''函數定義時,是否需要返回值,視情況而定'''

五、變數的作用域

變數的作用域:程式程式碼能存取該變數的區域

  1. 區域性變數:在函數內定義並使用的變數,只在函數內部有效,區域性變數使用global宣告,這個變數就會變成全域性變數
  2. 全域性變數:函數體外定義的變數,可作用於函數內外
# -*- coding: utf-8 -*-
# @File  : demo.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/14 17:02

# 變數的作用域:程式程式碼能存取該變數的區域
'''
1.區域性變數 在函數內定義並使用的變數,只在函數內部有效,區域性變數使用global宣告,這個變數就會變成全域性變數
2.全域性變數 函數體外定義的變數,可作用於函數內外
'''

def fun(a, b):
    c = a+b  # c,在函數內定義的變稱為區域性變數  a,b為函數的形參,作用範圍也在在函數內部,相當於區域性變數
    print(c)

name = '阿偉'  # 函數外部定義的變數,全域性變數,函數體內外都可以使用
print(name)  # 阿偉

def fun2(self):
    print(name)
# 函數呼叫

fun2(name)  # 阿偉

def fun3():  # 函數定義
    global age  # 函數內部定義的變數,區域性變數  使用global宣告,變數就變為全域性變數
    print(age)  # 20

age = 20
fun3()  # 函數呼叫
print(age)  # 20

六、程式碼複用

  函數是程式的一種基本抽象方式,它將一系列程式碼組織起來通過命名供其他程式使用。函數封裝的直接好處是程式碼複用,任何其他程式碼只要輸入引數即可呼叫函數,從而避免相同功能的程式碼在被呼叫處重複編寫。程式碼複用有另一個好處,當更新函數功能時,所有被呼叫處的功能都被更新。

  程式由一系列程式碼組成,如果程式碼是順序但無組織的,不僅不利於閱讀和理解,也很難進行升級和維護。當程式長度在百行以上,如果不劃分模組,程式的可讀性就已經很糟糕了。解決這一問題最好的方法是將一個程式分割成短小的程式段,每一段程式完成一個小的功能。使用函數對合理劃分為功能模組,並基於模組設計程式是一種常用方法,被稱為“模組化設計”。

  模組化設計是指函數的封裝功能將程式劃分成主程式、子程式和子程式間關係的表達。模組化設計是使用函數設計的思考方法, 以功能塊為基本單位,一般有兩個基本要求:

  • 緊耦合:儘可能合理劃分功能塊,功能塊內部耦合緊密;
  • 鬆耦合:模組間關係儘可能簡單,功能塊之間耦合度低。

   使用函數只是模組化設計的必要非充分條件,根據計算需求合理劃分函數十分重要。一般來說,完成特定功能或被經常複用的一組語句應該採用函數來封裝,並儘可能減少函數間引數和返回值的數量。

七、遞迴函數

1.什麼是遞迴函數

如果在一個函數的函數體內呼叫了該函數本身,這個函數就稱為遞迴函數。

2.遞迴的組成部分

遞迴呼叫遞迴終止條件

3.遞迴的呼叫過程

每遞迴呼叫一次函數,都會在棧記憶體分配一個棧幀,每執行完一次函數,都會釋放相應的空間。

4.遞迴的優缺點

缺點:佔用記憶體多,效率低下
優點:思路和程式碼簡單

使用遞迴函數計算階乘

# 1.使用遞迴函數計算階乘
def fun(n):  # 階乘函數
    if n == 1:
        return 1
    elif n == 2:
        return 2
    else:
        return n * fun(n-1)

print(fun(6))  # 720

斐波那契數列

# 2.斐波那契數列 1 1 2 3 5 8 13 ...
def fib(n):  # 斐波那契函數
    if n == 1:
        return 1
    elif n == 2:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)  # 求斐波那契數列的第 n 項

print(fib(6), end=' ')  # 8

八、總結

  • 函數使用def定義
  • *args定義個數可變的位置形參
  • **kwargs定義個數可變的關鍵字形參
  • 變數=值定義預設值形參
  • 函數呼叫的實參:位置實參關鍵字實參
  • 變數的作用域:區域性變數全域性變數

到此這篇關於Python基礎學習之函數和程式碼複用的文章就介紹到這了,更多相關Python函數和程式碼複用內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com