Python學習,第八課 - 函式
本次講解函式,由於內容比較多,小編列了個大綱,主要有一下內容:
1. 函式基本語法及特性
2. 函式引數
3.區域性變數
4. 返回值
5.巢狀函式
6.遞迴
7.匿名函式
8.高階函式
9.內建函式
1. 函式基本語法及特性
函式的定義:函式是指將一組語句的集合通過一個名字(函式名)封裝起來,要想執行這個函式,只需呼叫其函式名即可
函式的特性:
- 減少重複程式碼
- 使程式變的可擴充套件
- 使程式變的易維護
函式的語法定義
直接上程式碼:
# def 是定義函式的關鍵字 def test():#test既是函式名 print('學習Python的第一個函式') test() #呼叫函式
同時函式也可以帶引數
a, b = 1, 3 # 帶參函式 def test(x, y): # x 和 y 即是在我們呼叫函式時傳入的引數 return x + y # 返回執行的結果 c = test(a, b) # 把函式返回結果賦值給 C print(c)
2. 函式引數
在說函式引數前,大家需要了解一個知識點,形參 & 實參
何為形參?
既變數只有在被呼叫時才分配記憶體單元,在呼叫結束時,即刻釋放所分配的記憶體單元。
因此,形參只在函式內部有效,函式呼叫結束返回主呼叫函式後則不能再使用該形參變數
何為實參?
既可以是常量、變數、表示式、函式等,無論實參是何種型別的量,在進行函式呼叫時,它們都必須有確定的值,以便把這些值傳送給形參。
因此應預先用賦值,輸入等辦法使引數獲得確定值
這麼說可能有些不理解,還是來個例項讓大家更加清晰:
a, b = 1, 3 def test(x, y): # x 和 y 即是形參 return x + y c = test(a, b) # a,b既是實參 print(c)
關鍵引數
上面的例子中,我們呼叫函式傳參是根據函式的形參位置來傳遞的。
既 a 傳給 x ,b 傳給 y。這種叫做位置引數。
我們還可以使用關鍵引數,既傳遞的時候給函式的引數名傳遞你的值:
a, b = 1, 3 # 帶參函式 def test(x, y): return x + y c = test(y=a, x=b)#這裡把 a 傳給 y , b 傳給 x print(c)
這樣引數就可以不用按照順序傳遞,根據引數名傳遞給函式。
我們甚至可以把位置引數和關鍵引數同時使用:
a, b = 1, 3 def test(x, y): return x + y c = test(1, y=b) print(c)
如果同時使用一定要注意:關鍵引數必須要放在位置引數的後面,並且已經傳值的位置引數不能再用關鍵引數
下面是一些錯誤的用法:
c = test(x=a, b) #報錯:TypeError: test() got multiple values for argument 'x' c = test(a, x=b) #報錯:TypeError: test() got multiple values for argument 'x'
預設引數
引數還可以設定一個預設值,這樣我們在呼叫的時候既可以不傳參給預設引數
def test(x, y, z=9): # 設定了 z 的預設值是 9 print(x + y + z) test(1, 3)#如果我們第三個引數也就是z 不傳的話,z的預設值就是9 test(1, 3, 10)#我們傳了第三個引數,則 z 的值就變成10
非固定引數
所謂非固定引數就是可以傳遞任意個數的引數,比如你的函式在定義的時候不能確定使用者想傳入多少個引數,就可以使用
def test(*args): # 使用 *args, 這裡args可以改成任意變數名,但是不建議這麼做。 print(args) test() # 輸出結果:() test(1, 2) # 輸出結果:(1, 2) test(1, 2, '承受', 'Python') # 輸出結果:(1, 2, '承受', 'Python')
呼叫函式可以傳入任意個數的引數,然後轉換成 元組 的形式
3.區域性變數
區域性變數:就是隻能在區域性使用的變數
name = 'Cheng Shou' def change_name(name): print('改變前:', name) name = '承受' print('改變後:', name) change_name(name) print('在外面在看下name的值:', name) #輸出結果: #改變前: Cheng Shou #改變後: 承受 #在外面在看下name的值: Cheng Shou
從上面的例子大家發現了沒?函式裡面的name修改了,函式外面的name沒有改變。
其實函式裡面的name 就是區域性變數,他並沒有呼叫外部的name。
那函式裡面就不能使用全域性變量了嗎?非要用也是可以的
name = 'Cheng Shou' def change_name(): global name #在函式中使用global既可 print('改變前:', name) name = '承受' print('改變後:', name) change_name() print('在外面在看下name的值:', name) #輸出結果: #改變前: Cheng Shou #改變後: 承受 #在外面在看下name的值: 承受
使用global 既可,我們的全域性變數也被修改了。
當然不建議這麼做。
全域性變數與區域性變數
在子程式中定義的變數稱為區域性變數,在程式的一開始定義的變數稱為全域性變數。 全域性變數作用域是整個程式,區域性變數作用域是定義該變數的子程式。 當全域性變數與區域性變數同名時: 在定義區域性變數的子程式內,區域性變數起作用;在其它地方全域性變數起作用
4. 返回值
其實我們第一個例子中就有用到返回值,既 return 語句。return可以吧函式的執行結果返回
返回值記住兩點:
1.函式在執行過程中只要遇到 return 語句就會停止函式的執行,並且返回結果。所以 return 語句出現就代表著函式結束
2.如果函式中未使用 return ,那函式執行完畢後,返回的值為 None
5.巢狀函式
顧名思義就是函式裡面套函式,小編看到這個也是內心驚呼一聲:python 果然牛掰
那麼怎麼套呢,上程式碼:
name = 'Cheng Shou' def change_name(): name = '小承' def change_name2(): name = '小受' print('第三層:', name) change_name2() # 呼叫記憶體函式 print('第二層:', name) change_name() print('最外層:', name) #輸出結果: #第三層: 小受 #第二層: 小承 #最外層: Cheng Shou
神奇吧,一層套一層,跟俄羅斯套娃一樣
至於這個巢狀函式什麼作用,之後學習到裝飾器的時候我們就知道了。
6.遞迴
在函式內部,可以呼叫其他函式。如果一個函式在內部呼叫自身本身,這個函式就是遞迴函式。
說白了,就是在函式裡面呼叫自身函式
def subtraction(n): print(n) if n < 1: return n return subtraction(n-1) subtraction(5) #輸出結果: #5 #4 #3 #2 #1 #0
注意:python預設的遞迴深度是很有限的(預設是1000),因此當遞迴深度超過999的樣子,就會引發這樣的一個異常。
報錯:RecursionError: maximum recursion depth exceeded while calling a Python object
如果你的業務需要遞迴深度超過1000,則需要修改遞迴深度的值
import sys sys.setrecursionlimit(10000)
匯入sys模組,然後設定,需要多大就設定多大既可。
一般我們的業務程式碼不建議超過預設深度,否則程式碼效能不好。
在二分查詢的時候,我們會用到遞迴,不過這講到演算法問題本篇就直接帶過,後續有時間小編在寫一篇演算法相關的文章
遞迴特性:
1. 必須有一個明確的結束條件
2. 每次進入更深一層遞迴時,問題規模相比上次遞迴都應有所減少
3. 遞迴效率不高,遞迴層次過多會導致棧溢位(在計算機中,函式呼叫是通過棧(stack)這種資料結構實現的,每當進入一個函式呼叫,棧就會加一層棧幀,每當函式返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞迴呼叫的次數過多,會導致棧溢位)
7.匿名函式
匿名函式就是不需要顯式的指定函式
def test(n): return n + 1 print(test(2)) # 上面的函式修改成匿名函式後 test = lambda n: n + 1 print(test(2))
一般匿名函式是和其它函式搭配使用的,如下
print(map(lambda x: x ** 2, [1, 2, 3, 4, 5]) ) #輸出:[1, 4, 9, 16, 25]
8.高階函式
變數可以指向函式,函式的引數能接收變數,那麼一個函式就可以接收另一個函式作為引數,這種函式就稱之為高階函式。
簡單的說就是把函式當做引數傳遞給另一個函式,在函式中呼叫傳遞過來的函式。
def add(x, y, func): return func(x) + func(y) def square(n): return n ** 2 res = add(3, 6, square) print(res)
這裡把square函式,傳遞給了add ,並且在add中使用了 square函式。這便實現了高階函式
9.內建函式
直接展示一張圖,不做詳解,大家使用到的時候在瞭解既可。
&n