Last Updated on 2021-03-28 by Clay
『函式』(function) 是程式語言結構的一部分,我想我們可以簡單定義為『包裝好後可以多次呼叫使其執行的程式元件』。
基本上,若你有機會去網路上搜尋一下 "clean code",你會看到更多關於 function 以及 class 的說明 ——這些程式設計的概念若是清楚,那麼你可以選擇直接跳過這個章節,這邊對你而言可能太過簡單,我怕會消耗到你的時間。
當然,在 Python 的程式設計當中一直不乏平鋪直敘的『腳本派』與使用 function、class 將功能包好的『C派』(抱歉,以上這些都是我自己的定義稱呼 XDDD 可以不用太過認真。)
但是,就算只是將 Python 視為一個只需能執行自己想要的功能即可的『腳本派』工程師,也是有必要學會 function 的使用 —— 因為這能省下大量的時間!
定義一個 function
其實之前的教程裡的 sample code 有使用到 function,只不過我希望能在這裡再次簡單說明該怎麼定義一個 function。
首先,先從最經典的『費氏數列』 (Fibonacci numbers) 開始,這裡也會帶到一點遞迴的概念,不過,我想等之後有機會提及『如何使用 Python 進行數獨解題』時,再來解清楚關於『遞迴』的概念。
在這裡先補充一下小知識:
斐波那契數列(義大利語:Successione di Fibonacci),又譯為菲波拿契數列、菲波那西數列、斐氏數列、黃金分割數列。
Wikipedia
在數學上,費氏數列是以遞迴的方法來定義:
- F0=0
- F1=1
- Fn= Fn-1+Fn-2(n≧2)
用文字來說,就是費氏數列由0和1開始,之後的斐波那契系數就是由之前的兩數相加而得出。首幾個斐波那契系數是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233……(OEIS中的數列A000045)
以上便是維基百科對於費氏數列的介紹,連原本的連結我都保留著,有興趣也歡迎多閱讀其他相關的知識。
中間的三個式子便是費氏數列的定義了。
以下,我們便基於這三個式子,使用 "def" 這個符號進行 function 的定義。
def fibo(n): if n == 0: return 0; elif n == 1: return 1; return fibo(n-1) + fibo(n-2)
完成了!
咦?有人一定很疑惑,這樣就完成了那個看起來麻煩的要死的三個數學式子了嗎?
沒錯,function 裡面的三行,恰恰就等於那三個數學式子:
- 定義 f(0) 是 0
- 定義 f(1) 是 1
- 定義 f(n) 是 f(n-1) + f(n-2)
"def" 這個指令如同剛才所說,是定義 function 的指令,要牢牢記住哦!
fibo 這個函式名是可以自己取的,不過建議取得有意義一點,不然程式剛開始寫好的時候只有你和上帝看得懂,過兩三個禮拜——只剩上帝看得懂啦!(我常發生這種事情。)
然後『縮排』的部份即為 function 內定義的程式碼,只要呼叫函式,就可以執行裡頭的程式碼。
至於 fibo(n) 中的 n,便是傳入函式內的 n 值了,function 會根據我們傳入的值決定底下程式碼執行時 n 的大小。
return 的部份,即為 function 傳回給予我們變數的值,等下會實際演練。
先來講解一下程式碼吧。
我相信 n == 0 以及 n == 1 經過前幾回的課程後大家想必早就看膩了,那麼我先來解說關於 return fibo(n-1) + fibo(n-2) 的部份。
簡單來講,我們在準備要 return 回傳值的時候,又再次呼叫了 fibo() 這個函式!而且這一次,函式輸入的 n 值為最開始輸入的 n 值的 -1, -2。
這其實正是所謂的『遞迴』,我們會不斷呼叫更小的 n 值來執行程式,直到其符合我們程式的 if n == 0 以及 if n == 1 時才會停下,不再呼叫自己。
也許用圖表來看會更清楚。
假設我們輸入的是 fibo(5):
從一開始的 function 分裂到最後, fibo(0) 回傳的值為 0, 只有 fibo(1) 會回傳 1,那麼最終結果會是什麼呢?
ans = fibo(5) print(ans)
Output:
5
ans 為我們最終的回傳值,結果是不是正如大家的猜想呢?
那麼以上就是我們關於 function 功能的講解,最後再囉唆一下:你可以將你想要多次執行的功能先寫好,然後在每次需要的時候呼叫這個函式。
相信我,這會很方便的!