---
# System prepended metadata

title: 函數
tags: [python]

---

# 函數
###### tags: `python`
```python=
def function_name(引數):
    do_something...
    return something
```
一個函數由Key Word關鍵字「`def`」定義。後方緊接著函數的「名稱」，小括號內放「引數」，也就是可以放一些變數讓使用者根據需求輸入。
冒號後換行縮排填入這個函數要做的事情。
最後是這個函數回傳一個東西。
## 判斷是否為倍數
當我們想要判斷一個數是否為另一個數的倍數，我們可以這麼做：
```python=
firstNumber = 60
secondNumber = 15
if (firstNumber % secondNumber == 0):
    print("%d是%d的倍數。" % (firstNumber, secondNumber))
else:
    print("%d不是%d的倍數。" % (firstNumber, secondNumber))
```
那如果我們想要連續判斷好幾組數字呢？
```python=
firstNumber = 60
secondNumber = 15
thirdNumber = 18
if (firstNumber % secondNumber == 0):
    print("%d是%d的倍數。" % (firstNumber, secondNumber))
else:
    print("%d不是%d的倍數。" % (firstNumber, secondNumber))
if (firstNumber % thirdNumber == 0):
    print("%d是%d的倍數。" % (firstNumber, thirdNumber))
else:
    print("%d不是%d的倍數。" % (firstNumber, thirdNumber))
```
我們發現copy and paste 雖然好用，但隨著東西越來越多，整個版面會變得一直重複、複雜、難以閱讀。
這時候我們可以把重複、類似的事情用函數來化簡：
```python=
def printIf(number, isMultipleOf):
    divisor = isMultipleOf
    if (number % divisor == 0):
        print("%d是%d的倍數。" % (number, divisor))
    else:
        print("%d不是%d的倍數。")

        
# 按照定義的順序填入參數
printIf(60, 15)
# output: 60是15的倍數。

# 填入參數時指定
printIf(number=60, isMultipleOf=15)
# output: 60是15的倍數。

printIf(number=60, isMultipleOf=18)
# output: 60不是18的倍數。
```
這邊我們定義一個函數名為 `printIf`，並且有兩個參數`number`、`isMultipleOf`。
使用的方法就是呼叫他，並且填入適當的參數。例如`printIf(number=60, isMultipleOf=15)`。（你可以嘗試唸整句就變成 print if number 60 is multiple of 15。）

另一種寫法，我們可以判斷完之後回傳結果就好，而不印出來：
```python=
def isNumber(firstNumber, multipleOf):
    secondNumber = multipleOf
    if (firstNumber % secondNumber == 0):
        return True
    else:
        return False


print(isNumber(60,15))
# output: True

a = 60
b = 15
if isNumber(firstNumber=a, multipleOf=b):
    print("%d是%d的倍數。" % (a, b))
# output: 60是15的倍數。
```
兩種函數的寫法差別在，前者判斷完之後直接印出結果；後者判斷完之後，回傳結果，但不做任何多餘的事。
若一個函數影響到、修改原本的程式，我們稱作「side effect（副作用）」。也就是像前者，直接在原本程式印出結果的動作。
一般而言，做成後者的形式比較好，讓函數只回傳結果，而不對原本的程式進行修改。讓寫程式的人在結果回傳後決定後續的處理。

### Advance
我們可以將函數寫成：
```python=
def isNumber(firstNumber: int, multipleOf: int) -> bool:
    secondNumber = multipleOf
    if (firstNumber % secondNumber == 0):
        return True
    else:
        return False 
```
我們增加的這些東西是「annotation（註解）」，也就是告訴別人這個地方要做什麼。例如：`firstNumber: int`告訴別人`firstNumber`是一個整數；`-> bool` 告訴別人這個函數會回傳一個布林值。
（在python中，語法上沒有要求一定要寫。這些註解甚至不影響函數的運作，你可以把`int`改成「整數」或是隨意的文字都可以。萬一你輸入的是浮點數，而非整數，這個程式也不會跟你報錯。）

當我們需要輸入不確定個數的參數時，可以用`*`：
```python=
def greet(*to):
    for people in to:
        print(f'Hola {people}!')

greet("Kyle", "John", "Amy")
# Hola Kyle!
# Hola John!
# Hola Amy!
```

## Wrapping up
我們現在可以將重複的事情變成函數，除了簡潔之外，更易於維護。在python裡，函數可以回傳任何東西，包括（之後會學到的）串列等等。



