歡迎光臨
我們一直在努力

我和Python的Py交易》》》》》》函式

文章摘要: have_name() # 用函式名呼叫函式 have_name函式名是指被封裝的程式碼呼叫函式時傳給函式的引數

一 函式是什麼?  是數學中的函式?

Python中 函式是指將一組語句的集合通過一個名字 (函式名) 封裝起來的一段程式碼。(所以這裏的函式是 subroutine子程式 )

那要函式幹嘛。不都是程式碼嗎?只不過函式是通過一個名字被封裝起來的一段程式碼。 有名字就就了不起啊!!!

對啊,有名字就是了不起啊,函式可以通過 函式名來呼叫 被其封裝起來的程式碼。

可以理解為是一個 變數 ( 函式名 )指向的一段程式碼。這個變數( 函式名 )只是一段 沒有執行 的程式碼, 變數() ( 函式名() )是表示 執行 這段程式碼 。

函式的作用

1.程式碼重用

例如:一段用來求兩數之和的程式碼通過一個函式名封裝成 一個函式 , 每當需要 求和功能時就不用在把這段程式碼敲出來了,直接用函式名來 呼叫 這段程式碼

這樣這一段求被封裝成函式的求和程式碼就被 重複的使用 了很多次。(還省了你敲程式碼的時間)

2.保持一致性

每一個呼叫的函式都是同一個,程式碼都都是一樣的。

3.易擴充套件性

因為函式保持一致性,所有修改函式,為函式新增新功能時,只要修改一次,所有呼叫的該函式都會跟著變。

 二 建個函式玩玩

Python 定義函式使用 def 關鍵字( Definition n  定義 )

def 函式名(引數列表):
    函式主體(被封裝起來的一段程式碼)

def have_name():
    print('有名字就是了不起!')
have_name()  # 用函式名呼叫函式  have_name函式名是指被封裝的程式碼,have_name()代表是執行這段程式碼。

函式名的命名規則:

  • 函式名必須以下劃線或字母開頭,可以包含任意字母、數字或下劃線的組合。不能使用任何的標點符號;
  • 函式名是區分大小寫的。
  • 函式名不能是保留字。

想要寫出高質量的程式碼,規範的命名是必不可少的。期待吧,少年,我會開單章隨筆來,叨叨這個命名的。

形參和實參

形參 : 形式上的引數,是應函式的 需求 虛擬出變數。當呼叫這個函式時,就會傳一個引數( 實參 )給形參,這樣虛擬的變數就變真實了( 實參個數,型別應與實參一一對應 );

實參 :實際引數,呼叫函式時傳給函式的引數, 可以是常量,變數,表示式,函式,傳給形參 ;

打個比喻來形象的說明形參和實參的關係,在數學的函式 F(X)=X+1 中,X就是形參( 這個時候X不代表任何具體的值 ),而當把X=1帶人這個F(X)函式時,1就是實參。

區別 :形參是虛擬的,不佔用記憶體空間,形參變數只有在被呼叫時才分配記憶體單元,實參是一個變數,佔用記憶體空間。

def tow_sum(a,b):  #這個裡的a和b是沒有分配記憶體空間的
    c=a+b          #這裏的a和b是分配了記憶體空間的
    print(c)

tow_sum(1,2)       # 1和2 是實參為其分配了記憶體空間

三 和函式形參的促膝長談

函式的形參可以是 各種資料(數字,字串,元組,列表,字典等),函式名等……

函式形參(引數)

  • 關鍵字引數
  • 預設引數
  • 非關鍵字可變長引數(元組)
  • 關鍵字可變長引數(字典)

關鍵字引數 : 標準呼叫 時指定引數的名稱,且與函式宣告時的引數名稱 順序一致 。使用 關鍵字呼叫 引數允許函式呼叫時引數的順序與宣告時 不一致 ,僅根據引數的指定進行賦值。

def gu(a,b):
    if a==1:
        print('鐘鼓饌玉不足貴,但願長醉不復醒。')
    if b==2:
        print('古來聖賢皆寂寞,惟有飲者留其名。')

# 標準呼叫
gu(1,1)
#鐘鼓饌玉不足貴,但願長醉不復醒。

# 關鍵字呼叫(可以不按順序)
gu(b=2,a=1)
# 鐘鼓饌玉不足貴,但願長醉不復醒。
# 古來聖賢皆寂寞,惟有飲者留其名。

預設引數 : 在函式宣告時,指定形參的預設值,呼叫時可不傳入改引數( 使用預設值 )。

def gu(a=1,b=0):
    if a==1:
        print('鐘鼓饌玉不足貴,但願長醉不復醒。')
    if b==2:
        print('古來聖賢皆寂寞,惟有飲者留其名。')

gu()
#鐘鼓饌玉不足貴,但願長醉不復醒。

gu(2,2)
#古來聖賢皆寂寞,惟有飲者留其名。

gu(b=2,a=0)
#古來聖賢皆寂寞,惟有飲者留其名。

非關鍵字可變長引數(元組) :「 非關鍵字 」「 可變長 」顧名思義是允許在呼叫時傳入多個「 非關鍵字 」引數,python會將這些多出來的 引數放入一個元組中 。

def gu(*s):
    print(type(s))
    print(s)

gu(1,'鐘鼓饌玉不足貴,但願長醉不復醒。',2,'古來聖賢皆寂寞,惟有飲者留其名。')   #可變長,愛有幾個引數就調幾個引數

#   元組
# (1, '鐘鼓饌玉不足貴,但願長醉不復醒。', 2, '古來聖賢皆寂寞,惟有飲者留其名。')

關鍵字可變長引數(字典) :「 關鍵字 」「 可變長 」顧名思義是允許在呼叫時傳入多個「關鍵字」引數,python會將這些多出來的 <引數名, 引數值>放入一個字典中 。

def gu(**s):
    print(type(s))
    print(s)
    print(s['a'])
    print(s['b'])

gu(a= "鐘鼓饌玉不足貴,但願長醉不復醒。", b= '古來聖賢皆寂寞,惟有飲者留其名。')  #可變長,愛有幾個引數就調幾個引數

#   字典
# {'a': '鐘鼓饌玉不足貴,但願長醉不復醒。', 'b': '古來聖賢皆寂寞,惟有飲者留其名。'}
# 鐘鼓饌玉不足貴,但願長醉不復醒。
# 古來聖賢皆寂寞,惟有飲者留其名。

需要注意的是當它們 混用時 ,關鍵字變數引數應該為函式定義的最後一個引數,帶** 。 呼叫函式時引數的輸入也有不同的方式。

def gu(a,b,*c,**d):
    print(a)
    print(b)
    print(c)
    print(d)
gu(1,2,3,f=7,g=8)

# 1
# 2
# (3,)
# {'f': 7, 'g': 8}

def gu(a,b,*c,**d):
    print(a)
    print(b)
    print(c)
    print(d)
gu(1,2,*('鐘鼓饌玉不足貴,但願長醉不復醒',),**{'t': '鐘鼓饌玉不足貴,但願長醉不復醒。', 'f': '古來聖賢皆寂寞,惟有飲者留其名。'})

# 1
# 2
# ('鐘鼓饌玉不足貴,但願長醉不復醒',)
# {'t': '鐘鼓饌玉不足貴,但願長醉不復醒。', 'f': '古來聖賢皆寂寞,惟有飲者留其名。'}

四 給回扣的返回值

要想獲取函式的執行結果,就可以用return語句把結果返回

return返回值可以是 各種資料(數字,字串,元組,列表,字典等),函式名等……

注意:

  1. 函式在執行過程中只要遇到return語句,就會停止執行並返回結果,so 也可以理解為 return 語句代表著函式的結束
  2. 如果未在函式中指定return,那這個函式的返回值為None,Python會自動給函式加 return None 。

  3. return多個物件,直譯器會把這多個物件 組裝成一個元組 作為 一個整體 結果輸出。
def gu(a):
   return a

b = gu('古來聖賢皆寂寞,惟有飲者留其名。')
print(b)

五 就是比你高的高階函式

高階函式是 至少滿足下列一個條件的函式 :

  • 接受一個或多個函式作為輸入( 引數 )
  • 輸出一個函式( return 返回值 )

遞迴函式,修飾器也都是高階函式的運用

六 鞭長莫及的作用域

作用域研究的是資料的 適用範圍 。

就像地球的重力加速度g在火星上就不適用。

def globe():
    g = 9.8

def mars():
    g = 3.71

上述程式碼中兩個g是 毫無關係的 ,因為 它們的作用域不同一個函式就是一個作用域 。在globe()中的g的只在globe函式中適用,另一個g也是是如此。

這只是作用域的小小體現, 作用域不只在函式中有,在類,包中都有體現 。還有如何去呼叫,修改不同作用域裡的資料 。

這些都會開單章來嘮叨一下。

七 自娛自樂的遞迴

定義:一個函式在內部呼叫自身本身,這個函式就是遞迴函式。

說白了就是自己和自己玩(單身人士都懂的)

注意:

1. 必須有一個明確的 結束條件 (不可自娛自樂太久要有個度)

2. 每次進入更深一層遞迴時,問題規模相比上次遞迴都應有所減少  (每自娛自樂一次總得緩解一下單身狗的苦)

3. 遞迴效率不高,遞迴層次 過多 會導致棧溢位。 (自娛自樂多了傷身)

註釋:(在計算機中,函式呼叫是通過棧(stack)這種數據結構實現的,每當進入一個函式呼叫,棧就會加一層棧幀,每當函式執行結束,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞迴呼叫的次數過多,會導致棧溢位。)

階乘的計算

# **********迴圈*********
def factorial(n):
    result = n
    for i in range(1, n):
        result *= i

    return result

print(factorial(3))

# **********遞迴*********
def factorial_new(n):
    if n == 1:  # 遞迴結束條件
        return 1
    result=factorial_new(n - 1)
    result = n * result
    return result

a = factorial_new(3)
print(a)

遞迴函式是定義簡單,邏輯清晰。理論上,所有的遞迴函式都可以寫 成迴圈的方式 ,但迴圈的邏輯不如遞迴清晰。

八 良心的內建函式

內建函式就是Python提供的,可以直接使用的函式, 所以 內建函式一般都是使用頻繁的函式。

以後會仔細說一下有哪些內建函式

九 無副作用的函數語言程式設計

常見的程式設計正規化有 指令式程式設計 , 函數語言程式設計 。

指令式程式設計 :是面向計算機硬體的抽象,有變數(對應著儲存單元),賦值語句(獲取,儲存指令),表示式(記憶體引用和算術運算)和控制語句(跳轉指令), 命令式程式就是一個馮諾依曼機的按照打孔紙帶執行指令。

函數語言程式設計 : 是面向數學的抽象, 他將計算機運算看做是數學中函式的計算,並且避免了狀態以及變數的概念, 一句話, 函式式程式就是一個表示式 。

程序導向程式設計,物件導向程式設計 都是 指令式程式設計

函數語言程式設計的本質

函數語言程式設計中的 函式 這個術語不是指計算機中的函式,而是指 數學中的函式 ,即 自變數的對映 。也就是說一個函式的值僅決定於 函式引數的值 ,不依賴其他狀態。

我們要做的是把函式傳來傳去,而這個,說成術語,我們把他叫做高階函式 。

函式是基本單位,他幾乎被用作一切,包括最簡單的計算,甚至連變數都被計算所取代。

變數只是一個名稱,而不是一個儲存單元, 這是函數語言程式設計與傳統的指令式程式設計最典型的不同之處 。

函數語言程式設計取消了 賦值模型 ,則使 數學模型與程式設計模型完美地達成了統一 。

函數語言程式設計 關心 資料的對映 ,指令式程式設計 關心 解決問題的步驟。

#計算列表中數的平均值
#***********指令式程式設計***************
number = [0,1, 2, 3, 4, 5, 6, 7, 8, 9]
count = 0
add = 0

for i in range(len(number)):
        count += 1          # 第一步 計數
        add+= number[i]    # 第二步 求和

if count > 0:
    average = add/ count   # 第三步 計算平均數

print(average)


#***********函數語言程式設計***************
number = [0,1, 2, 3, 4, 5, 6, 7, 8, 9]
average = sum(number) / len(number)
print(average)

歡迎評論,番茄,雞蛋都砸過來吧!!!

未經允許不得轉載:頭條楓林網 » 我和Python的Py交易》》》》》》函式