Python中的函數


在上個章節中,我們提到了一些關於函數的基本概念—函數是一個自定義的運算符號,用來處理較為複雜的程式運算。函數就像一臺機器,你對它是輸入一些數值,它就對你輸出一些數值。


數學中的函數


函數這個東西,在數學上的應用相當的廣,還記得為我們都學過的直線方程式 $f(x)=2x+1$ 嗎?其中,$f(x)$就是一個函數,你對它輸入一個值,它就對你輸出一個值:假設將 $x$ 代 1 ,我們將會得到 3。

$$f(x)=2x+1$$
$$f(1)=2\cdot1+1=3$$

函數也可以有超過一個輸入。假設我們有一個函數,叫作$g(x, y)$,並定義為$g(x, y) = x+y$。假設今天我們將 $x$、$y$ 分別帶入 1、2,我們將得到 3 的結果。

$$g(x,y)=x+y$$
$$g(1,2)=1+2=3$$


Python 程式中的函數


在 Python 中,要定義一個函數是無比簡單的,就以剛剛的$f(x)=2x+1$的例子來看好了,如果要將其寫作 Python 的函數,我們可以這樣做:

def f(x):
    return 2*x + 1

讓我們先來是用一下這個函數,待會再來看看上面的程式中每一行代表什麼。我們試著將其印出:

print(f(1))

便會得到結果:

3

結果是不是與我們一開始所看到的$f(1)=3$相同呢?是的!接著,確認程式無誤後,我們可以來看看剛剛的程式中發生了什麼事。剛剛的程式是這樣的:

def f(x):
    return 2*x + 1

print(f(1))

在 Python 中,所有函數都要有相同的起始關鍵字 def,因此第一行中的 def 就是在告訴電腦「這裡有一個函數哦」。在 def 後,我們需要告訴電腦我們函數的名稱,在此,函數叫做 f。

在第二行中,我們用了 return 這個關鍵字,代表「會傳」,回傳的數值為 2*x + 1。因此,當我們在印出 f(1) 時,電腦便將數字 1 傳入函數,函數再將數字 3 傳回來。最後,print(f(1)) 就成了  print(3) 的意思,電腦即印出數字 3。

接著,讓我們試著將剛才的$g(x,y)=x+y$用 Python 寫出來吧!

def g(x, y):
    return x + y

是不是相當簡單呢?我們使用 def 關鍵字告訴電腦我們要建立一個函數 g,並用 return 關鍵字告訴電腦這個函數必須回傳 x + y 的值。因此,當我們試著:

print(g(1, 2))

就會得到:

3


函數中進行別的工作


從剛剛到現在,我們所舉例的函數都只有兩行程式:第一行程式用來宣告函數,第二行程式用來 return 函數的回傳值。但是,沒有人規定函數一定只能有一行,基本上,你可以想放幾行程式在函數中,就放幾行程式在函數中。

再進一步討論函數前,我們可以先在大腦中畫出一張函數的圖。在 Python 中,絕大多數你會看到的函數都是以這樣的結構定義的:

Python 函數定義 | def函數 | 程式設計

遇到這種多行的函數程式,最簡單易懂的理解方法就是使用 print() 函數,它可以告訴我們程式在哪一刻進行到什麼位置。讓我們先來看看以下的範例:

def add(x, y):
    print("在函數中")
    return x + y

x = 3
y = 5
print("函數還沒執行")
z = add(x, y)
print("函數執行完了")

我們可以看到的是,在這個範例中,函數中不只有 return 一行之長,而是有兩行所構成。切記,在同一個 Python 程式中,縮排的大小必須相等,例如上述例子中的第二和第三行,縮排就都是四個空格。

接著,請你仔細看看程式中的三個 print() 函數,你覺得在執行程式後,哪一個會先被印出來呢?我們可以試著執行看看,執行後會得到這樣的結果:

函數還沒執行
在函數中
函數執行完了

為什麼?我們其實可以將程式的每一行拆開來看,看看電腦對於上述程式的執行順序為何,我們從第五行的變數宣告開始:

1. 執行 x = 3
    宣告出一個變數 x。

2. 執行 x = 3
    宣告出一個變數 y。

3. 執行 print("函數還沒執行")

   (跳入 add 函數)
4. 執行 print("在函數中")

5. 執行 z = 3 + 5
    宣告出一個變數 z,
    並且將其設為 add 的回傳值。

6. 執行 print("函數執行完了")


無回傳值的函數


還記得剛剛講到數學中的函數嗎?在數學中,有一個很重要的函數特性是,只要有輸入,就要有一個對應的輸出。然而,在程式中,函數不一定要遵守這個規則,也就是說,程式中的函數不一定要有 return

這種不回傳值的函數,稱作無回傳值函數void function)。但是,如果函數不回傳任何的值,那這個函數的意義是什麼?答案是:簡化現有的程式碼。

假設我們要製作一個程式,程式中有 x 和 y 兩個變數,我們希望印出 100 組不同 x、y 的和、差、積、商。想要寫這個程式,我們應該會這麼做:

x = 2
y = 3
print(x + y)
print(x - y)
print(x * y)
print(x / y)

x = 3
y = 7
print(x + y)
print(x - y)
print(x * y)
print(x / y)

# .
# .
# .
# 共 100 組
# .
# .
# .

x = 0
y = 4
print(x + y)
print(x - y)
print(x * y)
print(x / y)


好的,在經過了 99 次的複製貼上後,我們得到了上述這樣的程式,看起來不錯吧!但是如果今天我們的題目變了,在你寫完這上面這個程式之後,你發現其實只要 print() 兩個數字的差和積就好了,那麼在你改完程式後,是不是又要再重複複製貼上 99 次呢?

其實,上面這段程式可以使用不同的寫法達到相同的功能,而且在修改時將會方便很多。我們可以利用不回傳值的函數,把上面一直重複出現的段落包裝起來,並且將 x、y 組合變成一個陣列,這麼一來,我們將得到這樣的程式:

def printValue(x, y):
    print(x + y)
    print(x - y)
    print(x * y)
    print(x / y)

xySet = [[2, 3], [3, 7], ...共100項..., [0, 4]]

for xy in xySet:
    printValue(xy[0], xy[1])

這麼一來,就算題目真的改成印出 x、y的差和積,我們也只要改變兩行程式:將函數 printValue() 中的多餘程式刪掉就好了。

仔細比較的話可以發現,這個函數跟我們前面所提到的函數,以及我們所熟知數學中的函數不太一樣—這個函數沒有回傳的值,也就是沒有 return。於是我們瞭解,函數不一定要回傳值,假設今天有很多重複的相同程式碼,我們可以將其放入一個沒有回傳的函數中,提高程式的可讀性以及修改速度
上一章節
下一章節
使用者分享的影片來自 YouTube。瞭解更多
+1 
感謝內容貢獻者 此篇文章由 1 位使用者共同編輯而成,並且由學呀的編輯團隊負責維護。點此查看編輯者名單。