### ch4-1:文字輸入與輸出的技巧 def hello(): print("Hello!") def sayHi(name, title): print(name + title + "你好!") hello() sayHi("王小明", "同學") >>> sayHi("王小明", title = "同學") >>> sayHi(title = "同學", name = "王小明") >>> sayHi(title = "同學", name = "王小明") # 錯誤,位置參數要在指名參數之前 ### ch4-2:help() 查詢函數參數用法 >>> help(print) >>> help(len) ### ch4-3:指定參數的預設值 def calc(w, h, d = 1): return w * h * d print(calc(3, 4)) # 算面積 print(calc(3, 4, 5)) # 算體積 ### ch4-4:有預設值的參數必須定義在最後 def sayHi(name, title = "先生", hi = "你好"): print(name + title, hi) print(sayHi("王小明", hi = "好久不見") # hi 重新指定參數。title 無指定,使用預設 ### ch4-5:使用 return 來傳回物件 def calc(w, h): if(w < = 0 or h <= 0): return return w * h print(calc(3, 4)) # 輸出 12 print(calc(3, -4)) # None,函式無傳回值 def calc(w, h): return ((w + h) * 2, w * h) print(calc(3, 4)) # 傳回值是一個 tuple ### ch4-6:「變數多重指定」及「容器自動解包與打包」,也都適用於函式的傳回值上 def calc(w, h): return [((w + h) * 2, w * h), "正方形" if w == h else "長方形"] a = calc(4, 5) print(a) ((a, b), c) = calc(4, 5) print(a, b, c) ### ch4-7:函式和變數、容器一樣都是物件 def calc(w, h): return w * h a = calc # 將函數物件指派給變數 a print(a(2, 3)) # 用 a() 一樣可以呼叫 calc() 函式 ### ch4-8:把函式當成參數來傳遞 s = [(3, 4), (2, 4), (5, 3)] # s 為多組 tuple (寬, 高) 的 list 容器 def calc(w, h): # calc() 將被當作參數傳入 calcAll() return w * h def calcAll(conta, func): # 參數為容器 (例如:s) 及函式物件 (例如:calc) for r in conta: # 走訪容器 print(func(r[0], r[1]), end = ' ') # 以元素的寬、高為參數,呼叫 func 函式 calcAll(s, calc) # 把容器 s 及函式 calc 傳入 calcAll() ### ch4-9:不定數目的參數 *args 和 **kwargs def prnSum(name, *args): # 不定數目參數通常會以 args 為名 print(name, args, '=', sum(args)) prnSum("加總", 1, 2, 3, 4) # 1, 2, 3, 4 會打包成 tuple 指定給 args ### ch4-10:定義在「*參數」前面的參數都不可省略,定義在「*參數」後面的,只能是指名參數或 **kwargs def prnSum(name, pre = '>', *args, post = '#'): print(name, pre, args, '=', sum(args), post) prnSum("加總", ':', 1, 2, , 4, post = '元') ### ch4-11:使用 **kwargs 來接收不定數目的指名參數 def prnPrice(name, **kwargs): # 不定數目的關鍵字 (指名) 參數,通常會以 kargs 為名 print(name, kwargs) prnPrice("飲料", 紅茶 = 40, 咖啡 = 70, 果汁 = 85) ### ch4-12:在呼叫函式時, 可用 *、** 將容器解包 def prnPrice(name, *args, **kwargs): print(name, args, ':', kwargs, sep = '') dscnt = ("早餐 8 折", "消夜 9 折") drink = {"紅茶": 40, "咖啡": 70, "果汁": 85} prnPrice("飲料", *dscnt, **drink) ### ch4-13:lambda 匿名函式 s = [(3, 4), (2, 4), (5, 3)] # s 為多組 tuple (寬, 高) 的 list 容器 def calcAll(rects, func): # 參數為容器 (例如:s) 及函式物件 for r in rects: # 走訪容器 print(func(r[0], r[1]), end = ' ') # 以元素的寬、高為參數,呼叫 func 函式 calcAll(s, lambda w, h: w * h) ### lambda:必要時還是可以給它綁定一個名字 calc = lambda w, h: w * h # 等同於使用傳統方式定義 calc print(calc(3, 4)) # 同樣可以當成函式來呼叫 ### lambda 決定了每個元素的計算方式 calcAll(s, lambda w, h: w * h) # 等同於使用傳統方式定義 calc calcAll(s, lambda w, h: (w + h) *2) # 同樣可以當成函式來呼叫 ### ch4-14 s = [(3, 4), (2, 4), (5, 3)] print(sorted(s, key = lambda e: e[1])) ### ch4-15:變數的有效範圍 (Scope Rule) a = b = c = 1 # 建立 a, b, c 三個全域變數 def test(b): # 參數 b 為區域變數 a = 2 # 建立區域變數 a print(a, b, c) # 輸出區域變數 a, b,及全域變數 c test(3) # 輸出 2 3 1 print(a, b, c) # 輸出 1 1 1 ### ch4-16:global 宣告:在函式中變更全域變數值 a = b = c = 1 # 建立 a, b, c 三個全域變數 def test(b): # 參數 b 為區域變數 global c # 定義函式時,指名要使用全域變數 c a = 2 # 區域變數 a c = 33 # 因為已經宣告 global c,所以這個 c 是指上層的全域變數,而非新建一個區域變數 print(a, b, c) # 輸出區域變數 a, b,及全域變數 c test(3) # 輸出 2 3 33 print(a, b, c) # 輸出 1 1 33 ### ch4-17:容器物件的 scope rule s = [1, 2, 3] # 在最上層程式中,建立串列 s t = [4, 5, 6] # 在最上層程式中,建立串列 t def test(a): # 若以 test(s) 呼叫時,參數 a 會綁定到傳入的串列 s a[0] = "aaa" # 透過區域變數 (參數) a,更改串列 s 的元素 t[0] = "ttt" # 在函式內透過全域變數 t,直接更改串列 t 的元素 s = [7, 8, 9] # s[0] = "sss" print(a, t) test(s) print(s, t)