5. 函式的使用與進階語法

tags: Python

以下程式碼「有」先後順序

推薦影片教學頻道:

函式與特殊語法在所有的程式語言裡面都是相當重要的概念!!!
所以請大家一定要好好學習這一段的內容!!!

名稱 定義 使用
函式 functions 將程式碼包裝起來 方便隨時重複使用 減少程式複雜度 建立 => 使用
關鍵字 keywords 程式語言原先就具備的函式 不可以 使用

一、函式 Functions

其實程式中的函式與我們數學中的函式式非常相似的
數學: f(x) = y
程式: f(arg) = return-value

簡單來說:

數學函式流程:
使用函式 => 給予 x => f(x) => 計算計算計算 => 得到 y

程式函式流程:
呼叫函式 => (給予參數值) => function(參數值) => 執行函式內的程式 => 取得回傳值

※ 這邊舉個 數學函式 與 程式函式 的例子 ※

數學函式: 
f(x) = 7x+9 = y

Python 函式: 
def f(x):
    return x*7+9

很簡單吧? 兩個式一樣的功能,都是計算: x 乘以 7 加 9
那實際上的 使用 當然不只這樣,但是 語法 就是這樣了 結束 函式 -KO
那我們開始寫幾個函式吧

1. 定義函式的結構:

2. 在函式中使用參數

  1. 在定義函式的時候,我們括號內,有幾個參數名稱,之後呼叫就必須放幾個參數值

例如: 我想計算3個數字 長length 寬width 高height 相乘的結果 => 就是立方體積啦~

def counting(length, width, height): #需要三個參數來使用,分別是 長 寬 高 result = length*width*height #計算 長 乘 高 乘 寬的結果並儲存到變數 result 裡 return result #回傳結果 result = counting(5,6,7)#呼叫函式 #計算長=5 寬=6 高=7 的立方體體積 儲存回傳值到變數result print(result) #印出結果
  1. 我們也可以預先設定好參數值 就不需要每次呼叫都必須輸入了

例如: 員工的薪水加成 加成的趴數固定 10% 那我們可以先預設趴數的參數為10

#定義 函式名稱為 CountMoneyBonus #並且我們希望使用時 最少 輸入一個參數Original 將輸入參數存到變數名稱input中 def CountMoneyBonus(Original, Bonus=10): return Original+Original/100*Bouns #直接計算並回傳 原薪水+加成多少錢 #員工Caitlin今年工作做得很認真 可以給他一點薪水加成 原本薪水是23000 依照固定10%加成 #指定23000以 原薪水(Original) 放入函式 print(CountMoneyBonus(Original=23000)) #計算 23000 加成10% 後的薪水 回傳 並印出 #員工LeeFuuChang 今年表現非常非常非常好 給他加成40%薪水 原薪水為30000 #指定30000以 原薪水 Original放入函式 40以加成 Bonus放入函式 print(CountMoneyBonus(Bouns=40, Original=23000))#計算加成後的薪水 回傳 並印出
#先來看看sum()可以做什麼 #定義一個列表 list numbers = [1,2,3,4,5,6,7,8,9,10] print(sum(numbers)) #取得回傳值 => 55 (因為1加到10 等於 55) 並印出

那現在換我們來重現一下它吧

#那麼我們來看看我們可以怎麼製作我們自己的 加總函式 吧 # 定義 函式名稱為 mysum 並且我們希望使用時輸入一個參數 將輸入參數存到變數名稱input中 def mysum(input): #先暫時將定義加總結果預設為0 result = 0 #try 嘗試 避免出現 Error try: #if 判斷 是否輸入的列表裡的物件的資料型態 type 是否 全部 all 都不是字串 str if all(type(check_type) != str for check_type in input): #for 迴圈 一一提取輸入的列表中的物件 持續更新加總結果 直到全部物件都加過一次 for each_num in input: #當前加總結果 + 提取數字 = 新的加總結果 result += each_num #return 回傳 加總結果 return result #else 如果有字串在輸入列表中 直接回傳原本輸入的列表 else: #return 回傳 原本輸入的列表 return input #except 如果加總過程出錯 直接回傳原本輸入的列表 except: #return 回傳 原本輸入的列表 return input

這樣就定義完了 那我們如何呼叫 / 使用這個函式呢
就跟 Python 原本給的一樣 Python給的是 sum(參數列表) 那我們的是 mysum(參數列表)

#定義一個列表 list numbers = [1,2,3,4,5,6,7,8,9,10] print(mysum(numbers)) #取得回傳值 => 55 (因為1加到10 等於 55) 並印出

這個例子中我們使用了以前教過的:

  1. 資料型態與基本運算
    定義變數 (result = 0)
    取得資料型態 type
    字串型態 str
    運算子 +=
  2. 流程控制
    判斷式 if else
    迴圈 for
    嘗試和例外 try except

另外 還有特殊用法:

1. all用法

all(type(check_type) != str for check_type in input)
用法:
 => all( (a 判斷運算子 b) for a in 列表)

可以用來判斷 列表裡的所有物件 是否 等於 大於 小於. . . b
如果是 回傳 True 否則 回傳 False

2. any用法

any(type(check_type) != str for check_type in input)
用法:
 => any( (a 判斷運算子 b) for a in 列表)
可以用來判斷 列表裡的任何一個物件 是否 等於 大於 小於. . . b
如果有 回傳 True 否則 回傳 False

既然剛好提到了 all any 用法,就順便介紹一些必較常見的特殊關鍵字吧

二、特殊關鍵字 Keywords

1. 特殊關鍵字的種類

判斷關鍵字 定義關鍵字 流程關鍵字 運算關鍵字 引入關鍵字
False def with、as lambda from
True class assert and import
None break or
continue not
pass、raise、yield is
if、elif、else in
global、nonlocal
try
except
finally
while
for
return
del

2. 定義關鍵字

(1) def

本篇 第一部分 內容
用於定義函式

(2) class

第八篇 OOP內容
用於 定義類別 也就是 自己寫一個資料型態

3. 判斷關鍵字

(1) False

就是 否、不正確的、不對的、NO、0 的意思

(2) True

就是 是、正確的、對的、YES、1 的意思

(3) None

就是 無、否、空、沒東西 的意思
在判斷 True False 時 None 會代表 False

4. 運算關鍵字

(1) and

代表「和」的意思
前後會分別搭配一個會回傳判斷關鍵字的功能或運算子
例如:

print((1+2 == 3) and (9-8 == 1)) #兩個都符合的話 就會印出True 有一個不合 則印出 False

.

(2) or

代表「或」的意思
前後會分別搭配一個會回傳判斷關鍵字的功能或運算子
例如:

print((1+2 == 3) or (2 == 1)) #兩個有一個符合的話 印出True 前後都不合 則印出 False

.

(3) is

代表「是否就是」的意思,用來判斷兩個資料是否 完全一致
這裡需要介紹到 id() 這個函式 / 功能,可以取得資料的 記憶體位置
如果兩變數的資料一樣 那可以用 == 運算子來判斷
但如果兩個變數的 記憶體位置 一樣 則可以用 is 和 == 來判斷
例如:

#我有兩個變數 a b a = 1000 b = 1000 print(id(a)) #印出變數a的 記憶體位置 print(id(b)) #印出變數b的 記憶體位置 print(a == b) #True 因為 1000 等於 1000 所以印出 True print(a is b) #False 雖然 變數值 相等 但是記憶體位置不同 所以印出 False

.

(4) not

代表「不是」的意思,通常用來反轉 True False
例如:回傳值雖然是False 但我希望回傳False的時候可以做些事情

#假設有一個函式 取得了回傳值 False 並存到變數 a 中 #為了不要太複雜 這邊就不花時間在做一個函式了 直接定義 a = False a = False # a = False 將 False 儲存到變數 a 中 if not a: # 如果 (不是 a) => (不是 False) => (True) => (正確) 所以執行 print("Excuted")

.

(5) in

代表「是否在裡面」的意思,用來判斷 a 是否在 b 內
例如 “Hello” in “Hello World!” => 輸出 True 因為 Hello 的確有在 Hello World! 裡

#定義兩個變數 a = "Hello" b = "hello World!" if a in b: #如果 a 在 b 裡面 回傳 True 正確 並執行 if 內的程式碼 print("Yes") #如果 if 是 True 印出 "Yes" # Yes 並不會被印出 因為 # "Hello" 並不在 "hello World!" 裡 # 因為我們在程式中大小寫也是會被納入判斷 # 所以 a 的 "Hello" 是大寫開頭 跟 b 不一樣 自然也就不存在於b裡面 所以是 False 不正確

.

(6) lambda

相當於 關鍵字def 用來定義簡易函式
例如: 取得兩數相加等於多少

func = lambda a, b : a + b #定義一個簡易函式 lambda 需要的參數為 a, b 兩個 : 會回傳 a+b print(func(100, 200)) # 印出 300 print(func(500, 900)) # 印出 1400 print(func(150, 25)) # 印出 175

.

5. 引入關鍵字

(1) from 、 import

這兩個基本上都是一使用的
用法: from 檔案名稱 / 資料夾名稱 import 模組名稱

#from 檔案名稱 / 資料夾名稱 import 模組名稱 #這邊用 time 時間模組 和 時間模組內的 sleep 功能 作為例子 import time from time import sleep # 然後使用引入的模組ㄐ

.

6. 流程關鍵字

(1) with 、 as

with 代表 「以」 as 代表 「作為」

# import 模組名稱 as 自訂名稱 這邊用 time 時間模組 和 時間模組內的 sleep 功能 作為例子 import time as t from time import sleep as s # 然後使用引入的模組 # with open( 檔案名稱 , 開啟模式) as 自訂名稱 # 這裡假設有個檔案叫 readme.txt 把它以唯獨模式 r 開啟 with open("readme.txt", "r") as f: #然後對檔案做事情

.

(2) del

代表「刪除」 用來 【完全刪除】 變數

a = 10 #變數名稱 a 用來儲存整數 10 del a #將 變數 a 完全刪除 b = a+1 #會出錯 因為 a 已經被我們刪除了 會出現 a 未被定義的錯誤

.

(3) if 、 elif 、 else

if 代表 「如果」
elif 代表 「不然如果」
else 代表 「不然」

a = int(input()) #向使用者取得輸入並轉為整數型態 if a>=10: print(" a 大於等於 10") elif a>=5: print(" a 小於10 大餘等於 5") else: print(" a 小於 5")

.

(4) try 、 except 、 finally

try 代表 「嘗試」
except 代表 「當出現錯誤」
finally 代表 「最後」

#閱讀下列程式的方法 #1. 嘗試 #2. 印出 x #3. 當出現錯誤時 #4. 印出 "x 未被定義 未被宣告 未被賦予任何資料" #5. 最後 #6. 印出 "掰掰" try: print(x) except: print("x 未被定義 未被宣告 未被賦予任何資料") finally: print("掰掰")

(5) while 、 for

while 代表 「當」
for 代表 「以」

while(True): # 當 True 的時候 持續一直執行 print("Hello World!") # 一直印出 "Hello World!" for _ in range(3): #以 _ 依序儲存範圍 [0, 1, 2] 三個數 print("Hello World!") #跑三次 所以印出三次

(6) break 、 continue 、 pass

break 代表 「退出迴圈」
continue 代表 「直接進入下一圈迴圈」
pass 代表 「跳過這一行」

a = 3 #從 3 開始找 while(True): #如果 a除與13的餘數加a除與17的餘數等於0 因為3只會是正數 #所以等於0代表兩個都是0 就印出 並退出迴圈 if a%13 + a%17 == 0: #由於我們每次只加 3 所以一定是 3 的倍數 所以不用檢查是否整除 3 print(a) break else: a+=3
a = 0 #從 0 開始找 b = [] # b 是個空列表 用來裝等等取得的數字 while(a+3<100): #a+3小於100才計算 if a+3 % 4 == 0: #如果 a+3 除與 4 的餘數等於0 => 整除 就 continue 跳過不印出 a+=3 continue else: a+=3 #否則 放入 b 列表 b.append(a) print(len(b)) #跳出會圈之後 印出有幾個符合
def func(value1, value2): #先定義好函式名稱 跟需要幾個參數 pass # 先 pass 掉 等等再來寫函式內的程式碼
  1. break 範例程式
  2. continue 範例程式

    .

(7) global 、 nonlocal

a = 10 # 加給你10%加權 夠多了吧~~~ def add(score): global a #繼承 主程式 的變數 a print(score*a/100) #印出 加多少分數 a = 20 #改變 變數 a 的值 return score*a/100 #回傳 加多少分數 add(100) print(a) #印出 20 #因為函式 繼承了主程式的變數 a 所以變動會直接影響到主程式的變數 a 的值
a = 0 #定義 a = 0 def layer1(): # 第一層函式 a = 1 #定義第一層函式中的 a = 0 def layer2(): #第二層函式 nonlocal a #繼承上一層函式的變數a a = 2 #改變變數 a 的值 print("layer2", a) # 印出 2 layer2() #呼叫 / 使用第二層函式 print("layer1", a) #印出 2 因為第二層函式繼承之後改變了 a 的值 layer1() #呼叫 / 使用第一層函式 print("Main", a) #印出 0 因為nonlocal不影響主程式變數
  1. global 範例
  2. nonlocal 範例

    .

(8) assert

Small_Mings_Score = int(input("請輸入小明的成績: ")) #向使用者要求輸入小明的成績 assert Small_Mings_Score >= 80 #檢查 小明的成績 Small_Mings_Score 大於等於 80 是否正確 print("恭喜~ 媽媽不生氣了") #如果正確 印出 "恭喜~ 媽媽不生氣了" 不正確 則丟出 AssertError
  1. 當輸入小明成績大於80
  2. 當輸入小明成績小於80

    .

(9) raise 、 return 、 yield

a = int(input("請輸入小明的成績: ")) if a < 80: raise BaseException("分數低於80 媽媽要生氣了") print("恭喜~ 媽媽不生氣了")
def count(r): area = r*r*3.14 #半徑 x 半徑 x 3.14 perimeter = 2*r*3.14 #直徑 x 3.14 return area, perimeter #回傳兩個值 分別是 面積 與 直徑 inputR = int(input("請輸入半徑")) #向使用者要求輸入半徑 GetArea, GetPerimeter = count(inputR) #由於回傳兩個值 需要用兩個變數名稱來接收並儲存 print("面積 = ", GerArea) # 印出 "面積 = " + 面積的值 print("周長 = ", GetPerimeter) # 印出 "周長 = " + 周長的值
#生成器寫法 def counting(): for i in range(10): yield i+1 a = counting() #用 a 儲存函式 counting 方便呼叫 print(next(a)) # 印出下一個a值 1 #做某些事情 print(next(a)) # 印出下一個a值 2 #做某些事情 print(next(a)) # 印出下一個a值 3 #做某些事情 #這樣就可以檢查 a 輸出到幾的時候出錯 能方便debug除錯
  1. raise 範例
  2. return 範例
  3. yield 範例