owned this note
owned this note
Published
Linked with GitHub
###### tags: `Python`
# 函式 def
**<a href="https://hackmd.io/@Mes/python_note" class="redlink">點此回到 Python筆記 目錄</a>**
#
# def 語法
之前我們已經用過了許多函式,像是 `print()`、`input()` 之類的,但這些函式的功能都是別人已經寫好的,那我們在寫程式的時候肯定會遇到一些重複的事情,如果也能把它變成函式的話不是很方便嗎? 舉個例子,我們現在要幫班上的同學買書,每加一本書就要把現在要購買的書的種類和價錢全部列出來,那我們可以這樣寫:
```python=
L = [ ["國文課本", 0], ["英文課本", 0], ["數學課本", 0], ["自然課本", 0], ["社會課本", 0] ]
while True:
print("現在要幫大家買書,如果你要加購,國文請輸入 1 ,英文請輸入 2 ,數學請輸入 3 ,自然請輸入 4 ,社會請輸入 5,如果沒有要加購了,請輸入 -1")
n = int(input("> "))
if(n == 1):
L[n-1][1] += 1
print(f"{L[n-1][0]}數量加一")
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
elif(n == 2):
L[n-1][1] += 1
print(f"{L[n-1][0]}數量加一")
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
elif(n == 3):
L[n-1][1] += 1
print(f"{L[n-1][0]}數量加一")
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
elif(n == 4):
L[n-1][1] += 1
print(f"{L[n-1][0]}數量加一")
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
elif(n == 5):
L[n-1][1] += 1
print(f"{L[n-1][0]}數量加一")
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
elif(n == -1):
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
print()
print("謝謝你,即將退出加購系統")
break
else:
print("無效的輸入,請重新輸入")
```
這邊為了舉例所以把它全部列出來了,我們也可以把 n == 1~5 的判斷句簡化成 `n <= 5 and n > 0` 。
上例中這段程式碼重複出現了好幾次:
```python=
L[n-1][1] += 1
print(f"{L[n-1][0]}數量加一")
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
```
每一個判斷式裡面的代碼塊基本上都大同小異,但我們卻必須重複的輸入這些程式碼,有沒有什麼方法可以避免呢? 這時候我們可以自己定義一個函式來解決這個問題,簡化我們的程式:
```python-
L = [ ["國文課本", 0], ["英文課本", 0], ["數學課本", 0], ["自然課本", 0], ["社會課本", 0]]
def buying (num):
if(num <= 5 and num > 0):
L[num-1][1] += 1
print(f"{L[num-1][0]}數量加一")
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
elif(num == -1):
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
print()
print("謝謝你,即將退出加購系統")
else:
print("無效的輸入,請重新輸入")
while True:
print("現在要幫大家買書,如果你要加購,國文請輸入 1 ,英文請輸入 2 ,數學請輸入 3 ,自然請輸入 4 ,社會請輸入 5,如果沒有要加購了,請輸入 -1")
n = int(input("> "))
if(n != -1):
buying(n)
else:
buying(n)
break
```
上例中我們自己定義了一個函式叫做 `buying()` ,而它的功能就是負責統計訂購的數量,因此在我們的 while迴圈 內就只要利用函式`buying()` 就可以完成統計的動作了。
那現在我們來看一下語法吧!首先會有關鍵字 `def` ,`def` 後方要接上函式的名稱,以上例來說就是 `buying` ,名稱的後方要接參數列表,前後用 `()` 包起來,以上例來講就是 `(num)` 這段,如此一來就好像宣告了一個變數一樣,可以供函式使用。
接下來我們看看函式的內容,`num` 是我們會傳入的參數,也就是在while迴圈內的 `n` ,接下來要做的事就跟前面一樣了,利用判斷句來統計訂購的數量。
<br>
那前面的章節有些函式會有回傳值,該怎麼做呢? 這時候就需要關鍵字 `return` 了,來看看下面這個例子,我們想要傳入小於三個數字,並把他們加起來:
```python=
def add(a = 0, b = 0, c = 0):
return a + b + c
s = add(1,1,1)
print("s = ", s)
print("add(1,1,1) = ", add(1,1,1))
print()
print ("add() = ", add ())
print ("add(1) = ", add ( 1 ))
print ("add(1,2) = " , add ( 1 , 2 ))
print()
#傳遞參數時可以不按照設定的順序進行傳遞
print ("add ( c = 50 , a = 100, b = 200 ) = " ,add ( c = 50 , a = 100, b = 200 ))
```
可以看見上例中的 `add()` 內多了關鍵字 `return`,`return` 後方會接上一個值或變數,並將它回傳,以上例來說就是回傳 `a+b+c` ,而上例中 `add()` 的參數列表內, a、b、c 的後方都多了 `=0` ,這是什麼意思呢? 意思是如果沒有傳入這個參數,我們就將它預設為指定的東西,也就是預設值,以上例來說就是 0 。 另外,如果我們知道參數的名稱,也可以不按照設定的順序傳入參數,就像是上例的最後一行那樣。
# 可變參數
上面那個加法的例子,最多只能有 3 個數字,那假設我們想要傳入更多數字,但並不知道最多會有幾個,該怎麼辦呢?這時候就需要可變參數了:
```python=
#在參數名前面的*表示args是一個可變參數
def add ( *args ):
total = 0
for val in args :
total += val
return total
#在呼叫add函數時可以傳入0個或多個參數
print ( add ())
print ( add ( 1 ))
print ( add ( 1 , 2 ))
print ( add ( 1 , 2 , 3 ))
print ( add ( 1 , 3 , 5 , 7 , 9 ))
```
上例中不管參數有多少個都可以進行加法,那我們來看看語法吧!
要使用可變參數,我們會需要在參數前面加上 `*` 號,這時程式會將你傳入的參數組成一個 Tuple ,以上例來說,`args` 會是一個 Tuple,內容就是我們傳入的東西,因此要使用傳入的參數時就會搭配 for迴圈 來取用參數。
# 同名問題
那假設我們有兩個相同名稱的函式會發生什麼呢? 可惜的是在Python內並沒有重載的概念,因此後出現的函式會覆蓋掉前面的函式:
```python=
def foo ():
print ( 'hello, world!' )
def foo ():
print ( 'goodbye, world!' )
foo ()
```
上例會輸出 goodbye, world 。
# 區域函式
在Python中,函式內還可以定義函式,這樣的函式我們稱它為區域函式 (Local function),那這有什麼用呢? 區域函式通常是為了方便函式定義時使用的,舉個例子:
```python=
L = [ ["國文課本", 0], ["英文課本", 0], ["數學課本", 0], ["自然課本", 0], ["社會課本", 0]]
def buying (num):
def print_List():
print("現在全部訂購數量為:")
for i in L:
print(i[0], ":", i[1], "本")
print()
if(num <= 5 and num > 0):
L[num-1][1] += 1
print(f"{L[num-1][0]}數量加一")
print_List()
elif(num == -1):
print_List()
print("謝謝你,即將退出加購系統")
else:
print("無效的輸入,請重新輸入")
while True:
print("現在要幫大家買書,如果你要加購,國文請輸入 1 ,英文請輸入 2 ,數學請輸入 3 ,自然請輸入 4 ,社會請輸入 5,如果沒有要加購了,請輸入 -1")
n = int(input("> "))
if(n != -1):
buying(n)
else:
buying(n)
break
```
上例中我們在 `buying()` 內又定義了 `print_List()` ,它的作用是印出表單,這種在函式裡面定義的函式,我們就稱它為區域函式。
要注意的是區域函式只能在函式內呼叫,以上例來說就是我們只能在 `buying()` 內呼叫 `print_List()` ,在 `buying()`外就無法呼叫它了,這也是它叫做 「區域」函式 的原因。
# 練習
### 練習1:利用函式蓋出輸入層數的星星塔
參考解答:
```python=
def print_star (n):
for i in range(n):
print( " "*(n-1-i) + "*"*(1+2*i) )
n = int(input("> "))
print_star(n)
```
<br>
### 練習2:利用函式將華氏溫度轉換為攝氏溫度。
參考解答:
```python=
def transform (f):
c = (f-32)/1.8
return c
f = float(input("請輸入華氏溫度 = "))
c = transform(f)
print("攝氏溫度 =", c)
```
# 額外補充
可變參數其實還有別種容器可以用,有興趣的可以看看這篇:
<strong><a href = "https://kknews.cc/zh-tw/code/9z9pvz8.html" class = "redlink">深入理解python的 *args 和 **kwargs 可變參數</a></strong>
<br>
課本下方還有提到變數範圍的問題,有興趣的可以看看:
<strong><a href = "https://github.com/jackfrued/Python-100-Days/blob/master/Day01-15/06.%E5%87%BD%E6%95%B0%E5%92%8C%E6%A8%A1%E5%9D%97%E7%9A%84%E4%BD%BF%E7%94%A8.md" class = "redlink">06.函數和模塊的使用.md</a></strong>
<style>
.green {
color:#29E5A9;
}
.brown {
color:#990000;
}
.pink {
color:#C18387;
}
.red {
color:#E71B18 ;
}
.blue {
color:#0b5394;
}
.purple {
color:#AC9FDD;
}
@-webkit-keyframes A
{
0% { color:#C10066;}
10% { color: #CC0000;}
20% { color: #E63F00; }
30% { color:#EE7700; }
40% { color: #DDAA00; }
50% { color:#EEEE00;}
60% { color: #99DD00;}
70% { color:#66DD00;}
80% { color: #00DDDD;}
90% { color: #0044BB;}
100% { color: #A500CC;}
}
#animation_title{
animation: A 3s ease 0s infinite alternate;
-webkit-animation: A 3s ease 0s infinite alternate;
}
</style>
<style>
a.redlink {
color:#DF2F6A;
}
a.redlink:link {
color:#DF2F6A;
text-decoration:none;
}
a.redlink:visiteid {
color:#DF2F6A;
text-decoration:none;
}
a.redlink:hover {
color:#19CABC;
text-decoration:none;
}
a.redlink:active {
color:#000000;
text-decoration:underline;
background:#FFFFFF;
}
</style>
<style type="text/css">
h1 {
font-size:;
color:#0b5394;
}
h2 {
font-size:;
color:#0b5394;
}
p {
font-size:;
color:;
}
h3 {
font-size: ;
color:#990000;
}
h4 {
font-size:;
color:#990000;
}
</style>