(Python)-初學 Class-7 — 函式

(Python)-初學 Class-7 — 函式

(Python)-初學 Class-7 — 函式

利用函式處理單一的特定功能

 

 

到目前為止,我們所學習過的 Python 操作和程式撰寫已經足夠我們寫出一個滿足特定功能的小程式。然而,一旦需要做的事情變多,我們的程式就會變得十分冗長,要做相同的事情還要將 同一段 code 重複貼上許多次。

為了避免發生上面的情況,我們需要函式來協助我們進行程式的撰寫。

 

函式是什麼?

不如我們就先從什麼是函式談起吧!所謂的 function 是一個建構程式時的小區塊,它就像是一台機器,你可以自行指定它的功能,以及所需要的原料(輸入)、產出(輸出)。

舉例來說,自動販賣機就像是一個 function ,他的 input 是硬幣和商品的選擇, output 則是你所選的商品。

既然它是一個機器,就代表在製作出這個 function 的時候,關於這個機器的規格(也就是輸入、輸出和功能)都要被規定好,要使用的時候,也只能依照著這個規定來使用它。

如此一來,在需要用到同一個操作的時候,只需要呼叫這個函式,就可以免去把同樣的程式碼不斷複製貼上的情況。

 

為什麼要使用函式?

那麼,函式到底有什麼我們非使用不可的理由呢?複製貼上也不過只是 ctrl+c、ctrl+v 兩個組合按鍵那麼簡單的事,假使我們不怕麻煩,函式的使用似乎並不是那麼直觀。

 

以下我們舉出幾個使用函式的優點:

程式的重複利用性:首先,是我們剛才所強調的,如果我們想要重複地做一件事,將這個功能寫成 function 會較為容易使用,不必擔心會不會在複製貼上時出了什麼差錯等等導致程式碼變 成一團混亂。

程式的易讀性:再者,將功能包裝成一個名稱明確的函式,能夠使其他人在閱讀你的程式碼時,更能理解這一個區段所要進行的操作是什麼,增加易讀性。

程式的易除錯性:寫成函式的好處還有較容易 debug 找出其中的錯誤,當發現程式所跑出的結果不如預期時,只需要檢查定義函式時有無差錯即可,不需要在使用同一個功能的每個段落都檢 查一次是否有邏輯上的問題,或是不小心更動了程式碼的內容。

程式的一致性:當程式的學習到了後來,與其他人一同撰寫一個大型專案是很常遇到的事情,此時如果你將你所寫的這一個功能包裝成一個 function 再傳給別人繼續作業時,就比較不會更 動到這個函式當中的內容,後續進行維護也較為容易。

程式的模組化:模組化是一個在撰寫程式時的概念,如果將寫一個完整的程式視為蓋一棟房子,那麼函式就像是房子的鋼筋、水泥、磚塊這樣的東西。程式是由許多個函式以及其他東西所建 構出來的,而且函式與函式之間的分工十分明確,每一個函式有它自己所負責的東西,並且可以獨立於這個程式來看,這樣的好處便形成了以上幾點優點。

 

如此一來,對於為什麼要使用函式 function 的理由應該十分充足了。

如何撰寫 Python 函式?

接下來要開始進入重頭戲,該如何寫一個 Python 函式呢?

 

def 函式名稱(參數): 程式碼

 

以上即為一個函式的基本架構,十分簡單,包含兩個區塊:

宣告:我們會利用 def 這個關鍵字來定義我們的 function ,包含函式名稱以及這個函式所需的參數。

程式碼內容:我們需要這個函式做什麼,就在這裡寫什麼程式碼。

簡單的舉個例子吧!假如我們今天想要寫一個判斷閏年的函式,那我們的想法可能會是,當我們輸入一個年份,然後針對這個年份進行判斷。

 

根據維基百科,分辨平閏年的方法為:

1. 公元年分除以4不可整除,為平年。

2. 公元年分除以4可整除但除以100不可整除,為閏年。

3. 公元年分除以100可整除但除以400不可整除,為平年。

也就是說,如果是閏年,那麼這個年份應該會是 400 的倍數,或者是 4 的倍數但卻不是 100 的倍數。

因此,我們可能會寫出如下的程式碼:

 

Learn 1 :

def check_leap_year(year):

    if (year % 400 == 0) or (year % 100 != 0 and year % 4 == 0):

        print("閏年")

    else:

        print("平年")

在寫完我們的函式以後,我們該如何呼叫(call)這個函式呢?假設我們今天的年份來自於輸入,那麼呼叫的方式可能如下:

year = int(input()) check_leap_year(year)

當然,我們在呼叫這個 function 時,並不需要將丟進 function 的變數名稱限制只能使用 year ,也可以是其他名稱,這裡只是暫時使用了相同的名稱。執行結果則是如下:

 

Learn  2 :

def check_leap_year(year):

if (year % 400 == 0) or (year % 100 != 0 and year % 4 == 0):

    print("閏年")

else:

    print("平年")

year = int(input()) check_leap_year(year)

2017 平年

 

需要特別注意的事情是,前面我們提到了, function 的規格(輸入、輸出和功能)是由我們定義的。因此,在執行 function 之前應該要事先思考過這個參數的 data type。

以上面的例子來說,假如你和圖中的程式碼一樣都將 year 這個變數視為整數來進行操作,那麼你在呼叫這個函式時就只能將整數形態的物件當作參數。如果你不小心疏忽了,錯將其他 type 的物件當成參數,那麼程式可能就會出錯。

TypeError: not all arguments converted during string formatting

並未確認 function 參數型態而產生的型別錯誤

除此之外,假如我們需要這個 function 回傳東西給我們使用,還有一個十分重要的部分:回傳值。

我們會使用 return 來回傳我們所需要的回傳值。我們使用和剛才同樣的例子,只是這次我們不讓他直接印出結果,而是回傳給我這個年份 “是不是” 閏年,也就是 True 或 False :

 

Learn 3 :

def check_leap_year(year):

if (year % 400 == 0) or (year % 100 != 0 and year % 4 == 0):

    return True

else:

    return False

year = int(input())

check_leap_year(year)

2019 ‘False’

以上的函式進行呼叫以後,執行結果

 

我們輸入了 2019 作為判斷的標的,並且將 check_leap_year 這個函式的回傳結果印出,得到結果為 False 。

最後,還需要特別注意的事情是, return 只能回傳單一的值,它可以回傳一個整數 int 、一個浮點數 float 、一個串列 list 、…等等,他可以回傳許多不同型態的物件,但是都只能回 傳一個。

那麼,如果我想要一次回傳多個值呢?如果我們想一次回傳多值,我們可以考慮將這些值包成一個元組 tuple 再將之回傳(關於 tuple 我們會在後面的章節再做介紹)。

 

Learn 4 :

def check_leap_year(year):

if (year % 400 == 0) or (year % 100 != 0 and year % 4 == 0):

    return True, "123"

else:

    return False, "456"

year = int(input())

print(check_leap_year(year))

print(type(check_leap_year(year)))

2019 (False, ‘456’) <class ‘tuple’>

一樣使用剛才判斷閏年的例子,我想要在判斷是閏年的時候,同時回傳字串 “123” ,而判斷是平年的時候,與 False 一同回傳 “456” 這個字串。

當我們嘗試輸出這個函式的回傳結果時,則會得到如上的結果

從印出的資料型態,我們可以看得出來此函式的回傳值是一個 tuple ,而且我們也一次得到了我們所需要的幾個值。

假如我們不想要得到一個 tuple 作為回傳值,而是希望兩個值都能個別被 assign 給不同的變數的話,該怎麼做呢?

 

Learn 5 :

def check_leap_year(year):

if (year % 400 == 0) or (year % 100 != 0 and year % 4 == 0):

    return True, "123"

else:

    return False, "456"

year = int(input())

is_leap, a = check_leap_year(year)

print(is_leap, type(is_leap))

print(a, type(a))

2019 False <class ‘bool’> 456 <class ‘str’>

 

我們可以嘗試用兩個變數來 “接住” 函數的回傳值,這樣我們便可以得到兩個分別被 assign 了不同值的變數,也完成了我們想要回傳多個值的目的。

 

 

免責聲明:

1.本影像檔案皆從網上搜集轉載,不承擔任何技術及版權問題

2.如有下載連結僅供寬頻測試研究用途,請下載後在24小時內刪除,請勿用於商業

3.若侵犯了您的合法權益,請來信通知我們,我們會及時刪除,給您帶來的不便,深表歉意。

 



發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *