# 2022-11-27 第三天 Python網路爬蟲應用實務班上課記錄 ###### tags: `python` `爬蟲` ## 函式 ```python= # 將一組成程式碼集中起來, 可以完成某件事或某個功能, 需要透過"呼叫"的手段來讓函式(或稱為函數)內的程式碼執行 # 1. 函式名稱可以是 數字, 英文大小寫, 底線的組合 # 2. 函式名稱第一個字不可以是數字 # 3. 不可以使用Python保留字 # 4. 可以使用跟內建函式名稱一樣的名字,但你會失去原本函式的功能,所以不建議 # 5. 函式名稱的大小寫視為不同名稱 # 小括號內定義該函式呼叫時要傳入多少個參數, 空的話表示不需要參數(或稱為引數) def my_first_func(): print('Hi my function') my_first_func() # 函式呼叫 my_first_func() # 函式呼叫 my_first_func() # 函式呼叫 # 有個參數的函式 def show_me(name): # 定一個呼叫時一定要傳入一個參數的函式 print(f'My name is {name}') # name參數對於show_me函式來說是一個"內部"變數 show_me('Aaron') # 呼叫show_me函式病傳入Aaron字串作為該函式內的name參數 show_me('Andy') # 呼叫show_me函式病傳入Aaron字串作為該函式內的name參數 show_me('Abner') # 呼叫show_me函式病傳入Aaron字串作為該函式內的name參數 # 有兩個參數的函式 def compare_num(a1, a2): if a1 > a2: print(f'{a1} 比 {a2} 大') else: print(f'{a1} 比 {a2} 小') compare_num(4, 8) # 參數傳入函式後會被依照參數的順序擺放 compare_num(48, 23) # 有三個參數的函式 def three_param(a, b, c): print(f'三個參數為: {a}, {b}, {c}') three_param('Test', 99, True) ``` #### 練習 ```python= # 寫一函式,名稱為 user_input,該函式功能為: # 1. 接受使用者輸入一個整數參數 # 2. 將該使用者輸入平方後顯示到畫面上 def user_input(num): print(f'{num ** 2}') user_input(20) user_input(12) ``` #### 參數預設值 ```python= # 參數預設值, 當呼叫函式如果沒有傳入該對應的參數,則直接使用一個預設值作為參數 def show_me(name = '無名氏'): print(f'My name is {name}') show_me('Aaron') show_me() # 有參數預設值的參數,右邊的參數全部都要有預設值 def check_num(a, b = -1, c = -1): print(f'{a}, {b}, {c}') check_num(1, 2, 3) check_num(1) # check_num() # 沒有參數預設值就醫定要傳入該參數 check_num(1, 2) def my_info(name, phone, addr): print(f'我的名字叫{name}, 電話是{phone}, 家裡地址{addr}') my_info(phone='0987654321', addr='台北市某個地方', name='Aaron') # 透過指定參數名稱的方式來傳入參數 ``` #### 回傳值 ```python= # 回傳值 # 函式在執行結束後可以產生資料回傳給呼叫方 def do_plus(a1, a2): print(f'總和: {a1 + a2}') total = a1 + a2 return total # 結束函式執行(類似迴圈內的break),並回傳後面的資料 total = do_plus(2, 3) # 接收函式回傳值 print(f'接受到回傳值: {total}') # 注意: 這個total和函式內的total為兩個不同的變數 # 打算把2 + 3的結果作平方 print(f'2和3加總後的平方為: {total ** 2}') ``` #### pack與unpack ```python= # 寫一函式swap, 可以用來交換兩個變數內的資料 def swap(a, b): return b, a # return 永遠只能回傳一筆資料, 這裡會pack兩筆資料成為一個tuple aa = 99 bb = 88 aa, bb = swap(aa, bb) print(f'aa = {aa}, bb = {bb}') c = swap(aa, bb) print(c, type(c)) # tuple 回憶 a = 3, 4, 5, 6, 7 print(a, type(a)) a, b, c = a # unpack tuple並存到三個變數內 print(a, b, c) ``` #### 一級函式 ```python= # 一級函式 # Python的函式就是一級函式, 函式本身就是一個物件(資料), 可以被存到變數內 def show_me(name): print(f'My name is {name}') # a = show_me() 這個是把show_me函式的回傳值存到a變數 a = show_me # 將show_me函式本體存到a變數 a('Aaron') def do_plus(a, b): return a + b def do_miner(a, b): return a - b def do_mux(a, b): return a * b def do_div(a, b): return a / b a = 10 b = 5 print( do_plus(a, b) ) # 一行程式碼有多個函式, 其呼叫順序為由內到外 print( do_miner(a, b) ) print( do_mux(a, b) ) print( do_div(a, b) ) def do_math(do_func, a, b): return do_func(a, b) print( do_math(do_plus, a, b) ) # 一行程式碼有多個函式, 其呼叫順序為由內到外 print( do_math(do_miner, a, b) ) print( do_math(do_mux, a, b) ) print( do_math(do_div, a, b) ) ``` #### callable() ```python= # callable() Python內建函式, 用來偵測某個變數內是不是函式, True=是函式, False=不是函式 def show(): print('Show') a = 2 print( callable(a) ) a = show print( callable(a) ) if callable(a) == True: a() else: print(a) ``` #### lambda函式 ```python= # LAMBDA 定義函式, 定義出來的函式"只有一行", 而且沒有名字 # def show(a, b): # print(a, b) # lambda定義完後可以直接呼叫 (lambda a, b: print(a, b))(2, 'Hi') # show(1, 'Hi') # 範例 def max(a1, a2): # if a1 > a2: # return a1 # else: # return a2 return a1 if a1 > a2 else a2 print(max(5, 6)) print(max(15, 9)) print(max(99, 54)) max2 = lambda a1, a2: a1 if a1 > a2 else a2 # 不需要加上return print(max2(5, 6)) print(max2(15, 9)) print(max2(99, 54)) print(type(max2)) ``` #### 拯救內建函式 ```python= # 拯救函式 a = [1, 2, 3, 4, 5] total = sum(a) print(total) b = [3, 4, 5, 6] sum = 0 for n in b: sum += n print('總和為:', sum) print(type(sum)) del sum # 把sum的功能刪掉(但不會刪掉python內建功能) total = sum([1, 2, 3]) # 此行會恢復Python內建sum函式的功能 ``` #### 練習 ```python= # 練習 # 1. 寫一函式, 名叫 check_score, 可以傳入一個整數參數, 如果數字大於等於60, 則回傳True, 如果小於60, 則回傳False # 2. 將上一個函式改用lambda來實現 def compare_score(a1): if a1 >= 60: return True else: return False a1 = int(input("請輸入分數:")) if compare_score(a1) == True: print('及格') else: print('不及格') compare_score = lambda a2: True if a2 > 60 else False a2 = int(input("請輸入分數:")) if compare_score(a2): print('及格') else: print('不及格') ``` ## 例外(exception) ```python= # 例外(exception) # 當程式執行時發生預期外"邏輯錯誤"造成的執行失敗而產生的結果 try: a = int(input('請輸入一個整數:')) # 當這裡產生例外,接下來同樣在try裡面的程式碼都會被忽略,並跳到except裡面執行 print(f'你輸入了: {a}, 平方值: {a ** 2}') a /= 0 except ValueError: # 捕捉ValueError例外 print('您輸入了非整數的資料') except ZeroDivisionError: # 捕捉ZeroDivisionError例外 print('發生除以0的例外') except Exception as e: # 將所有的例外都捕捉下來, 並將例外物件存到變數e裡面 print('發生例外了:', e, type(e)) else: print('都沒有例外發生的時候會執行else裡面的程式碼') finally: print('不管如何,都一定會被執行') # 當產生例外時,錯誤訊息的最後一行, 冒號前面的描述即為該例外名稱; 冒號後面為該例外的描述 # 當例外產生時,如果沒有處理,結果就會是程式被中斷執行 ``` #### 加上是否為數字的判斷 ```python= # 練習: 請幫猜數字遊戲加上輸入的資料是否為數的的判斷 guess_count = 0 # 紀錄猜了幾次 while True: player = input('請猜一個四位數的數字,數字不可重複:') guess_count += 1 # 次數加一 # 檢查輸入是否為數字 try: int(player) # 嘗試轉型成int except ValueError: print('只能輸入整數數字') continue except Exception: print('輸入有問題, 請重新輸入') continue # 檢查是否為四個數字 if len(player) != 4: print('數字只能四個,請重新輸入') continue # 檢查是否為四個不重複的數字 if len(set(player)) < 4: print('數字不可重覆, 請重新輸入') continue ``` ## 類別與物件 ```python= # 類別與物件 # 類別與函式一樣,定義好之後是不會被執行的 # 類別要執行之前,須要先產生物件才能被執行 # 類別內的函式(function)通常會改叫: 方法(method) # 類別內的變數(variable)通常會改叫: 屬性(attribute) class Car: def set_name(self, name): # 類別內的函式第一個參數永遠都是self self.name = name # self代表的是物件本身 def show_name(self): # 物件裡面的資料是物件內所有方法都可以共同使用的 print(self.name) def add_gas(self, gas): self.gas = gas def show_color(self): print(f'車子是: {self.color}的') c = Car() # 建立Car物件 c.set_name('BMW') c.show_name() c.color = '紅色' # 將紅色存到color屬性內 c.show_color() ``` #### 類別的預設方法 ```python= class MyItem: def __init__(self, name, age, tall): # 建構式, 物件被建立時自動被呼叫, 不必自己呼叫, 通常用來初始化物件用 self.name = name self.age = age self.tall = tall print('我被呼叫了') def show_info(self): print(f'我叫: {self.name}, 今年{self.age}, 身高{self.tall}公分') def __str__(self): # 此方法在物件被當字串使用時會自動呼叫 return f'我叫: {self.name}, 今年{self.age}, 身高{self.tall}公分' m = MyItem('Aaron', 18, 180) # 建立物件, 是個獨立的個體 n = MyItem('Andy', 20, 200) # 建立物件, 與m物件沒有關係 # n.name = 'Andy' # n.age = 20 # n.tall = 200 m.show_info() n.show_info() print(m) print(n) ``` ## 模組 #### my_module.py ```python= def hello(): print('hello') class Hello: def show(self): print('Show hello') hello_val = '你好' ``` #### main.py ```python= # 模組 import my_module my_module.hello() m = my_module.Hello() m.show() print(my_module.hello_val) ``` #### 引入模組的其他方式 ```python= import my_module as m # 在這個檔案內可以用m來呼叫my_module模組 m.hello() print(m.hello_val) ``` ```python= # from my_module import hello # 引入模組裡面指定的函式或變數或類別 # from my_module import hello_val from my_module import * # 將my_module裡面全部的功能都引入進來使用 hello() print(hello_val) h = Hello() h.show() ```