---
# System prepended metadata

title: 函式
tags: [人生苦短，我學Python]

---

# 函式
###### tags: `人生苦短，我學Python`

## 創建第一個函式
:::warning
```python=
def functionname([parameterlist]):
    ["comments"]
    ['functionbody']
```
:heavy_check_mark: functionname:函數名稱
:heavy_check_mark: parameterlist:可選參數，如有多個參數，須以","隔開
:heavy_check_mark: comments:可選參數，表示為函式指定註釋，通常表該函式功能
:heavy_check_mark: functionbody:可選參數，用於指定函式整體，如有返回值，可使用return字句返回

:middle_finger: 如想定義不做式的函式，可以使用pass做為佔位符
:warning: 請注意，縮排問題
:::
* 舉例
```python=
# 此程式碼無法運行，是因為twoSum()函式還沒有被呼叫
def twoSum(a, b)
    """
    兩個數字加起來
    """
    c = a + b
    return c
```

## 調用函數
:::danger
調用函數也就是執行函數，方法如下 :point_down: 
```python=
functionname([parameterlist])
```
:::

* 舉例
```python=
a, b = 2, 3
ans = twoSum(a, b)
print(ans)
# 5
```

## 參數傳遞
:::danger
```python=
def twoSum(a, b)

# twoSum => 函式名稱
# (a, b) => 函式參數
```
:bulb: 形式參數:在括號裡面的就是形式參數
:bulb: 實際參數:在調用的時候，函式括號裡的才是實際參數
:::

## 位置參數
* 數量必須一致
* 位置必須與定義時一致
```python=
def twoSum(a, b):
    c = a + b
    return c

print(twoSum(2))
# TypeError: twoSum() missing 1 required positional argument: 'b'
# 少了一個參數便動不了
```

## 關鍵字參數
:::success
呼叫函式時，在傳入參數值的前面加上函式所定義的參數名稱
:::

## 為參數設默認值
:::success
```python=
def funcname(parameter1 = defaultvalue1):
    pass
```
:bookmark_tabs: defaultvalue:可選參數，為該默認值
:::

* 範例
```python=
def twoSum(a, b = 3):
    return a + b

print(twoSum(5))
# 8
# 在沒有指定的情況下，b默認為3
print(twoSum(5, 5))
# 10
```
:::warning
:warning: 定義函式時，設置參數為默認值時須小心一點，默認參數必須指向不可變對象
:::

## 可變參數
* *parameter(可接收任意多個參數)
```python=
def add_all(*add):
    result = 0
    for i in range(len(add)):
        result += add[i]
    return result

print(add_all(1, 2, 3, 4, 5))
# 15
```

* **parameter，表示可接收任意多個類似關鍵字參數一樣顯示賦值的實際參數，並放進字典中
```python=
def printSign(**sign):
    print()
    for key, value in sugn.items():
        print(key, value)

printSign(a = "b", c = "d")
# a b 
# c d

# 如果需要導入的是一個字典
# dict = {"a" : "b", "c" : "d"}
# printSign(**dict)
```

## 返回值
* 也就是return，如果沒有return，即返回None空值

```python=
# 取自python tutor
def listSum(numbers):
    if not numbers:
        return 0
    else:
        (f, rest) = numbers
        return f + listSum(rest)

myList = (1, (2, (3, None)))
total = listSum(myList)
# 6
```

## 變量的作用域
* 局部變量(只能在函式裡呼叫)
```python=
def print_test():
    mes = "god"
    print(mes)

print_test()
print(mes)
# god
# NameError: name 'mes' is not defined
```
* 全域變量
```python=
mes = "god"
def print_test():
    print(mes)
    
print_test()    
print(mes)
# god
# god
```
:::warning
```python=
# 也可以改成global
mes = "god"
print("函數外 = ", mes)

def test():
    global mes
    mes = "mes id god"
    print("函數內 = ", mes)

test()
print("函數外 = ", mes)
# 函數外 =  god
# 函數內 =  mes id god
# 函數外 =  mes id god
```
:::

## 匿名函式
* 指的是沒有名字的函式，使用lambda表達式
```python=
result = lambda[arg1[arg2[.....]]]: expression
```
* 舉例
```python=
import math

def circlearea(r):
    return math.pi * r * r
    
print(circlearea(10))
# 314.1592653589793
# 上述寫法同等於 ......

import math

r = 10
result = lambda r:math.pi*r*r
print(result)
```

## 注意
:::warning
:warning: 注意函式的參數與默認值
:::


{%hackmd S1DMFioCO %}