文章摘要: 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返回值可以是 各種資料(數字,字串,元組,列表,字典等),函式名等……
注意:
- 函式在執行過程中只要遇到return語句,就會停止執行並返回結果,so 也可以理解為 return 語句代表著函式的結束
-
如果未在函式中指定return,那這個函式的返回值為None,Python會自動給函式加 return None 。
- 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)
歡迎評論,番茄,雞蛋都砸過來吧!!!