IoT MQTT Panel APP相關文章:
建立連結:本社群由Nantou.py使用者社群以及國立虎尾科技大學電機資訊學院負責維護,它是一群熱愛智慧生活科技以及Python的專業教師所組成,大家一同快樂地研究有關數位生活中人工智慧、大數據、物聯網、雲端服務、APPS、福祉科技、感知網路服務、車載網路服務、及網際網路等資通訊技術,並運用這些資通訊以及Python技術來提升我們的日常生活品質,建立更好的生活環境。
2025年11月12日 星期三
2025年11月10日 星期一
[水井USR創新教材]Python一下用爬蟲技術取得環境開放式資料
1 2 3 4 5 6 | import requests import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) r=requests.get('https://data.moenv.gov.tw/api/v2/acidr_p_01?format=json&offset=0&limit=5&api_key=KEY值請申請', verify=False) print(r.text) |
執行結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import requests import urllib3 import pandas as pd import json urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) r=requests.get('https://data.moenv.gov.tw/api/v2/acidr_p_01?format=json&offset=0&limit=5&api_key=申請的KEY值', verify=False) print(r.text) data = json.loads(r.text) records = data.get("records", []) df = pd.DataFrame(records) print(df.head()) df_selected = df[[ "sitename", "county", "township", "monitor_date", "item_name", "result_value", "item_unit" ]] print(df_selected.head()) |
[水井USR創新教材]Python一下用爬蟲技術協助水井村漁民取得市場交易行情
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import requests import urllib3 import json # 關閉 InsecureRequestWarning urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) url = 'https://data.moa.gov.tw/Service/OpenData/FromM/AquaticTransData.aspx' r = requests.get(url, verify=False) # 檢查 HTTP 狀態 if r.status_code != 200: print(f"資料取得失敗,HTTP 狀態碼:{r.status_code}") else: try: text = json.loads(r.text) for row in text: # 有些資料可能沒有「魚貨名稱」或「市場名稱」,需先檢查鍵存在 if '魚貨名稱' in row and '市場名稱' in row: if '吳郭魚' in row['魚貨名稱'] and '斗南' in row['市場名稱']: print('交易日期:' + str(row.get('交易日期', '無資料'))) print('品種代碼:' + str(row.get('品種代碼', '無資料'))) print('魚貨名稱:' + str(row.get('魚貨名稱', '無資料'))) print('市場名稱:' + str(row.get('市場名稱', '無資料'))) print('上價:' + str(row.get('上價', '無資料'))) print('中價:' + str(row.get('中價', '無資料'))) print('下價:' + str(row.get('下價', '無資料'))) print('交易量:' + str(row.get('交易量', '無資料'))) print('平均價:' + str(row.get('平均價', '無資料'))) print('-' * 40) except json.JSONDecodeError as e: print("JSON 解析錯誤:", e) except Exception as e: print("發生錯誤:", e) |
執行結果: 交易日期:1141109 品種代碼:1011 魚貨名稱:吳郭魚 市場名稱:斗南 上價:76.0 中價:63.6 下價:51.9 交易量:1631.0 平均價:63.8 ---------------------------------------- 交易日期:1141108 品種代碼:1011 魚貨名稱:吳郭魚 市場名稱:斗南 上價:76.7 中價:74.8 下價:72.5 交易量:1751.3 平均價:74.7 ---------------------------------------- 交易日期:1141107 品種代碼:1011 魚貨名稱:吳郭魚 市場名稱:斗南 上價:76.0 中價:66.6 下價:52.0 交易量:1636.3 平均價:65.6 ---------------------------------------- 交易日期:1141106 品種代碼:1011 魚貨名稱:吳郭魚 市場名稱:斗南 上價:76.0 中價:67.2 下價:59.3 交易量:1643.7 平均價:67.4 ---------------------------------------- 交易日期:1141105 品種代碼:1011 魚貨名稱:吳郭魚 市場名稱:斗南 上價:76.0 中價:63.4 下價:56.0 交易量:1593.1 平均價:64.5 ---------------------------------------- 交易日期:1141104 品種代碼:1011 魚貨名稱:吳郭魚 市場名稱:斗南 上價:76.0 中價:70.8 下價:63.6 交易量:1812.5 平均價:70.4 ---------------------------------------- 交易日期:1141102 品種代碼:1011 魚貨名稱:吳郭魚 市場名稱:斗南 上價:76.0 中價:64.0 下價:48.8 交易量:1704.5 平均價:63.4 ---------------------------------------- 交易日期:1141101 品種代碼:1011 魚貨名稱:吳郭魚 市場名稱:斗南 上價:76.0 中價:69.5 下價:58.1 交易量:1790.1 平均價:68.5 ----------------------------------------
[水井USR創新教材]Python一下用水井村故事學會 locals() 和 globals()
以下資訊是由ChatGPT協助生成:
在程式世界裡,
-
globals() 就像整個「水井村的地圖」🌏,記錄所有村子裡的名字(變數、函式、物件……)
-
locals() 就像「屋子裡的物品清單」🏠,只記錄某個房間(函式內部)的變數。
🏡範例 一、水井村全景地圖:globals()
水井村有許多居民與地標:烏龜、白馬、姻緣花。
這些都是「全域變數」,大家都能看到。
1 2 3 4 5 6 7 8 | # 水井村的全景地圖 village = "水井村" turtle = "烏龜" horse = "白馬" flower = "姻緣花" print("=== 水井村的全景地圖(globals) ===") print(globals().keys()) # 查看整個村子的地圖上有誰 |
執行結果:
globals() 會回傳一個字典(dict),裡面有所有全域變數的名字與內容。在這裡,它就像是整座村莊的登記簿。
🕳️ 範例二、進入烏龜的房間:locals()
現在,我們走進烏龜的房間。
裡面有牠自己的小物品(在地變數),這些東西村外的人看不到。
程式:
1 2 3 4 5 6 7 | def turtle_room(): food = "萵苣葉" toy = "石頭球" print("=== 烏龜房間裡的物品(locals) ===") print(locals()) # 查看房間裡的變數有哪些 turtle_room() |
執行結果:
1 2 3 4 5 6 7 8 | treasure = "金井水" def white_horse(): tool = "竹掃帚" print("房間內能看到 globals 嗎?", "treasure" in globals()) print("房間內能看到 locals 嗎?", "tool" in locals()) white_horse() |
執行結果:
- 在函式中列印出 locals()。
- 在外部列印出 globals()。
- 思考:函式外部能看到 boy 和 girl 嗎?
[水井USR創新教材]Python一下用水井三寶認識 Python 的 os 模組
以下教材是用ChatGPT生成。
在程式的世界裡,os 模組就像是我們在電腦裡旅行時的「導遊」,幫我們找到路、開資料夾、搬東西、檢查有沒有東西存在。
我們來看看三位主角——烏龜、白馬、姻緣花——是怎麼幫助我們理解 os 模組的!
範例一:🐢 烏龜:穩重的導覽員(os.getcwd / os.chdir)
烏龜總是走得慢但很穩,它最擅長「知道自己在哪裡」。
程式碼:
1 2 3 4 5 6 7 8 | import os # 烏龜看看自己現在在哪個資料夾 print("烏龜現在在:", os.getcwd()) # 烏龜想要換到另一個資料夾 os.chdir("C:/Users") # 換路徑 print("烏龜移動後的位置:", os.getcwd()) |
🗣 烏龜的智慧:
「知道當前路徑,才能慢慢走向下一個目標。」
1 2 3 4 5 6 7 8 9 10 11 | import os # 白馬看看這裡有哪些東西 print("白馬看到的東西:", os.listdir()) # 白馬替主人開一個新資料夾 os.mkdir("姻緣花資料夾") # 白馬幫忙確認檔案有沒有存在後再刪掉 if os.path.exists("舊檔案.txt"): os.remove("舊檔案.txt") |
1 2 3 4 5 6 7 8 9 10 11 | import os # 姻緣花幫兩段路徑牽在一起 path = os.path.join("C:/Users", "Documents", "水井村") print("姻緣花牽起的路徑:", path) # 看看這條緣分路上是否真的存在 if os.path.exists(path): print("這條路是真的有緣~") else: print("緣分還沒到,資料夾不存在。") |
執行結果:
💡小結論
| 角色 | 功能 | 對應 os 模組函式 |
|---|---|---|
| 🐢 烏龜 | 了解與改變當前位置 | os.getcwd()、os.chdir() |
| 🐎 白馬 | 整理、建立與刪除資料 | os.listdir()、os.mkdir()、os.remove() |
| 🌸 姻緣花 | 串接路徑與檢查存在 | os.path.join()、os.path.exists() |
- 讓烏龜顯示目前位置。
- 讓白馬建立一個新資料夾 三寶任務。
- 讓姻緣花檢查資料夾是否存在並印出結果。
2025年10月13日 星期一
[水井USR創新教材]Python一下用水井三寶來看字串正規表示式的用法
以下是用Grok AI生成。
以「水井三寶」(烏龜、白馬、姻緣花)為主題,設計一個 Python 小範例,展示如何使用隨機密碼生成器來產生與水井三寶相關的密碼。這個範例會結合物件導向程式設計(OOP)和 Python 的 random 模組,生成帶有三寶特色的密碼(例如包含「烏龜」、「白馬」、「姻緣花」的主題詞,並混雜隨機字元)。我們會使用封裝來管理密碼生成邏輯,並透過繼承讓每個寶物有獨特的密碼風格。
情境設定
假設我們要為水井三寶的每種寶物生成專屬密碼:
- 烏龜:密碼強調「長壽」,包含數字(年份)並較長。
- 白馬:密碼強調「迅捷」,包含特殊字元(象徵速度)並中等長度。
- 姻緣花:密碼強調「浪漫」,包含字母和愛心符號,較短但優雅。
每個密碼會結合寶物名稱、隨機字元(字母、數字、特殊符號),並確保安全性和隨機性。
範例程式碼
以下是一個完整的 Python 程式,展示如何用 OOP 和隨機模組生成水井三寶主題的密碼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | import random import string class Treasure: """基類:定義水井三寶密碼生成器的共同行為""" def __init__(self, name): self.name = name self._charset = string.ascii_letters + string.digits + string.punctuation # 基本字元集 def generate_password(self, length=8): """生成隨機密碼,包含寶物名稱""" random_part = ''.join(random.choice(self._charset) for _ in range(length - len(self.name))) password = self.name + random_part # 打亂密碼字元 password = ''.join(random.sample(password, len(password))) return password class Turtle(Treasure): """烏龜:生成長壽主題的長密碼,強調數字""" def __init__(self): super().__init__("烏龜") self._charset = string.digits # 烏龜密碼以數字為主 def generate_password(self, length=12): """覆寫:生成12位密碼,包含至少4個數字""" random_part = ''.join(random.choice(self._charset) for _ in range(4)) # 4個數字 extra_part = ''.join(random.choice(string.ascii_letters) for _ in range(length - 4 - len(self.name))) password = self.name + random_part + extra_part return ''.join(random.sample(password, len(password))) class WhiteHorse(Treasure): """白馬:生成迅捷主題的密碼,包含特殊字元""" def __init__(self): super().__init__("白馬") self._charset = string.punctuation # 白馬密碼以特殊字元為主 def generate_password(self, length=10): """覆寫:生成10位密碼,包含至少3個特殊字元""" random_part = ''.join(random.choice(self._charset) for _ in range(3)) # 3個特殊字元 extra_part = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length - 3 - len(self.name))) password = self.name + random_part + extra_part return ''.join(random.sample(password, len(password))) class MarriageFlower(Treasure): """姻緣花:生成浪漫主題的短密碼,包含愛心符號""" def __init__(self): super().__init__("姻緣花") self._charset = string.ascii_letters + "♥" # 包含愛心符號 def generate_password(self, length=8): """覆寫:生成8位密碼,包含至少1個愛心符號""" random_part = random.choice("♥") # 至少1個愛心 extra_part = ''.join(random.choice(string.ascii_letters) for _ in range(length - 1 - len(self.name))) password = self.name + random_part + extra_part return ''.join(random.sample(password, len(password))) # 測試範例 if __name__ == "__main__": # 創建水井三寶實例 turtle = Turtle() horse = WhiteHorse() flower = MarriageFlower() # 生成並展示密碼 treasures = [turtle, horse, flower] for treasure in treasures: print(f"{treasure.name} 的密碼:{treasure.generate_password()}") |
執行結果:
程式碼解析
- 正規表示式相關性:
- 雖然本題聚焦密碼生成,但可以延伸到正規表示式。例如,生成的密碼可透過 regex 驗證是否包含特定字元(例如 \d+ 檢查數字、[!@#$%^&*] 檢查特殊字元)。
- 範例中未直接使用 regex,但可添加驗證(見下方擴展建議)。
- OOP 技術應用:
- 繼承:Turtle、WhiteHorse 和 MarriageFlower 繼承 Treasure,共享基本密碼生成邏輯。
- 多型:每個子類別覆寫 generate_password,生成符合自身主題的密碼。
- 封裝:_charset 是保護屬性,控制可用的字元集。
- 類與實例屬性:name 是實例屬性,確保每個寶物有獨特名稱;_charset 在子類別中自訂。
- 隨機密碼生成:
- 使用 random.choice 從字元集中選取字元。
- 使用 random.sample 打亂密碼字元,增加隨機性。
- 每個寶物有不同長度和字元偏好:
- 烏龜:12位,強調數字。
- 白馬:10位,包含特殊字元。
- 姻緣花:8位,包含愛心符號 ♥。
- 安全考量:
- 密碼包含寶物名稱和隨機字元,並透過 random.sample 打亂,避免可預測性。
- 真實應用中應使用 secrets 模組(更安全),但為簡單起見這裡用 random。
[水井USR創新教材]Python一下用水井三寶來看字串正規表示式的用法
以下是採Grok AI生成的。
以「水井三寶」(烏龜、白馬、姻緣花)為主題,設計一個 Python 小範例來展示正規表示式(Regular Expression, regex)的應用。這個範例會結合物件導向程式設計(OOP)和正規表示式,聚焦於如何使用 re 模組來處理與水井三寶相關的文字資料。每個寶物會有一個專屬的正規表示式模式,用於解析特定格式的吉祥訊息,並展示 OOP 的封裝特性來管理正規表示式邏輯。
情境設定
假設我們有一段文字,包含水井三寶的吉祥訊息,例如:
- 「烏龜祝福:長壽100年」
- 「白馬祝福:奔馳500公里」
- 「姻緣花祝福:愛情99朵」 我們希望用正規表示式提取每個寶物的名稱和數值(例如年數、公里數、朵數),並透過類來管理這些模式和處理邏輯。
範例程式碼
以下是一個完整的 Python 範例,結合正規表示式和 OOP,並使用「水井三寶」來解析吉祥訊息。程式碼使用封裝來管理正規表示式,並提供簡單的處理方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import re class Treasure: """基類:定義水井三寶的共同行為""" def __init__(self, name): self.name = name self._pattern = None # 保護屬性:正規表示式模式 def extract_value(self, message): """提取訊息中的數值,使用正規表示式""" if not self._pattern: return f"{self.name} 尚未定義正規表示式!" match = re.match(self._pattern, message) if match: return f"{self.name} 提取到:{match.group(1)}" return f"{self.name} 無法解析訊息:{message}" class Turtle(Treasure): """烏龜:解析 '長壽X年' 的訊息""" def __init__(self): super().__init__("烏龜") # 正規表示式:匹配 "烏龜祝福:長壽數字年" self._pattern = r"烏龜祝福:長壽(\d+)年" class WhiteHorse(Treasure): """白馬:解析 '奔馳X公里' 的訊息""" def __init__(self): super().__init__("白馬") # 正規表示式:匹配 "白馬祝福:奔馳數字公里" self._pattern = r"白馬祝福:奔馳(\d+)公里" class MarriageFlower(Treasure): """姻緣花:解析 '愛情X朵' 的訊息""" def __init__(self): super().__init__("姻緣花") # 正規表示式:匹配 "姻緣花祝福:愛情數字朵" self._pattern = r"姻緣花祝福:愛情(\d+)朵" # 測試範例 if __name__ == "__main__": # 創建水井三寶實例 turtle = Turtle() horse = WhiteHorse() flower = MarriageFlower() # 測試訊息 messages = [ "烏龜祝福:長壽100年", "白馬祝福:奔馳500公里", "姻緣花祝福:愛情99朵", "烏龜祝福:無效訊息", ] # 遍歷寶物和訊息,展示正規表示式提取 treasures = [turtle, horse, flower] for treasure in treasures: print(f"\n測試 {treasure.name}:") for msg in messages: print(treasure.extract_value(msg)) |
程式碼解析
- 正規表示式(Regex)應用:
- 每個子類定義專屬的正規表示式模式,儲存在 _pattern 中:
- 烏龜:r"烏龜祝福:長壽(\d+)年" 提取年數(例如 "100")。
- 白馬:r"白馬祝福:奔馳(\d+)公里" 提取公里數(例如 "500")。
- 姻緣花:r"姻緣花祝福:愛情(\d+)朵" 提取朵數(例如 "99")。
- 使用 re.match 檢查訊息是否符合模式,並提取括號 (\d+) 中的數字。
- 每個子類定義專屬的正規表示式模式,儲存在 _pattern 中:
- 封裝(Encapsulation):
- _pattern 是保護屬性,儲存每個寶物的正規表示式模式,外部無法直接修改。
- extract_value 方法封裝了正規表示式的處理邏輯,提供統一的介面。
- 繼承(Inheritance):
- Treasure 是基礎類別,定義了共用的 name 和 extract_value 方法。
- Turtle、WhiteHorse 和 MarriageFlower 繼承 Treasure,並在 __init__ 中設定各自的正規表示式模式。
- 正規表示式的簡單說明:
- \d+:匹配一個或多個數字。
- ():捕獲括號內的內容,供 match.group(1) 提取。
- re.match:從字串開頭匹配,確保訊息格式正確。
技術亮點
- 正規表示式與 OOP 的結合:每個寶物類負責自己的正規表示式模式,符合單一職責原則。
- 封裝:正規表示式模式和提取邏輯被封裝在類內,外部只需呼叫 extract_value。
- 可擴展性:可以輕鬆新增其他寶物類,只需定義新的正規表示式模式。
2025年10月6日 星期一
[水井USR創新教材]Python一下用水井三寶來設計例外的範例
以下資訊是由AI工具協助生成
範例一:烏龜(Turtle) - 風水能量過載例外
文化背景:烏龜代表穩定的風水能量,但能量過高可能「破壞平衡」,就像風水過旺不利環境穩定。
情境:烏龜的能量(energy)有限制,超過 1000 會引發自訂例外,模擬風水能量過載。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | class TurtleEnergyOverloadError(Exception): """自訂例外:烏龜能量過載""" pass class Turtle: def __init__(self, energy=100): self.__energy = energy def recharge(self, amount): try: if amount < 0: raise ValueError("能量增量不能為負!") new_energy = self.__energy + amount if new_energy > 1000: raise TurtleEnergyOverloadError("烏龜能量過載,風水失衡!") self.__energy = new_energy return f"烏龜能量充滿:{self.__energy}" except TurtleEnergyOverloadError as e: return f"錯誤:{e}" except ValueError as e: return f"錯誤:{e}" def get_energy(self): return self.__energy turtle = Turtle(energy=900) print(turtle.recharge(50)) # 成功:烏龜能量充滿:950 print(turtle.recharge(100)) # 錯誤:烏龜能量過載,風水失衡! print(turtle.recharge(-10)) # 錯誤:能量增量不能為負! |
執行結果:
例外特性:
- 自訂例外:TurtleEnergyOverloadError 是自訂的例外類,模擬風水能量過載。
- 多重例外處理:捕捉 ValueError(負值輸入)和自訂的 TurtleEnergyOverloadError,展示如何處理不同類型的錯誤。
- 文化連結:烏龜的能量限制反映風水需要平衡的理念,過高能量會引發「失衡」。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | class LuckExhaustedError(Exception): """自訂例外:白馬好運耗盡""" pass class Treasure: def bless(self): return "寶物帶來吉祥!" class WhiteHorse(Treasure): def __init__(self, luck_points=100): self.luck_points = luck_points def bless(self): try: if self.luck_points <= 0: raise LuckExhaustedError("白馬好運已耗盡,請稍後再試!") self.luck_points -= 10 return super().bless() + f" 白馬帶來好運!剩餘好運點數:{self.luck_points}" except LuckExhaustedError as e: return f"錯誤:{e}" def ride(self): return "白馬奔馳,風水順暢!" horse = WhiteHorse(luck_points=20) print(horse.bless()) # 成功:寶物帶來吉祥! 白馬帶來好運!剩餘好運點數:10 print(horse.bless()) # 成功:寶物帶來吉祥! 白馬帶來好運!剩餘好運點數:0 print(horse.bless()) # 錯誤:白馬好運已耗盡,請稍後再試! |
執行結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class InvalidPrayError(Exception): """自訂例外:無效的祈求者""" pass class MarriageFlower: def bloom(self): return "姻緣花開,庄內好姻緣!" def pray(self, person): try: if not person or not isinstance(person, str): raise InvalidPrayError("祈求者名字無效,需為非空字串!") return f"{person} 向姻緣花祈求,好姻緣即將到來!" except InvalidPrayError as e: return f"錯誤:{e}" flower = MarriageFlower() print(flower.pray("小明")) # 成功:小明 向姻緣花祈求,好姻緣即將到來! print(flower.pray("")) # 錯誤:祈求者名字無效,需為非空字串! print(flower.pray(123)) # 錯誤:祈求者名字無效,需為非空字串! |
例外特性:
- 自訂例外:InvalidPrayError 用於檢查無效輸入,模擬姻緣祈求的條件限制。
- 輸入驗證:檢查 person 是否為非空字串,展示如何在例外處理中進行輸入驗證。
- 文化連結:姻緣花祈求需「真誠」(有效名字),反映文化中對姻緣的尊重。
2025年10月5日 星期日
[水井USR創新教材]Python一下用水井三寶來說明模組的用法
以上範例是由AI工成生成
範例一:水井三寶猜猜看
1 2 3 4 5 6 7 8 9 10 11 12 13 | import random def water_well_guess(): # 水井三寶 treasures = ["烏龜", "白馬", "姻緣花"] # 使用亂數選擇一個寶物 selected_treasure = random.choice(treasures) return selected_treasure # 測試函數 for _ in range(5): # 模擬抽取 5 次 result = water_well_guess() print(f"你從水井三寶中抽到:{result}") |
執行結果:
1 2 3 4 5 6 7 8 | import random def water_well_guess(): # 水井三寶 treasures = ["烏龜", "白馬", "姻緣花"] # 使用亂數選擇一個寶物 selected_treasure = random.choice(treasures) return selected_treasure |
1 2 3 4 5 6 | import guess # 測試函數 for _ in range(5): # 模擬抽取 5 次 result = guess.water_well_guess() print(f"你從水井三寶中抽到:{result}") |
執行結果:
1 2 3 4 5 6 | from guess import water_well_guess # 測試函數 for _ in range(5): # 模擬抽取 5 次 result = water_well_guess() print(f"你從水井三寶中抽到:{result}") |
執行結果:
2025年10月3日 星期五
[水井USR創新教材]Python一下用水井三寶來說明類別的重要概念
本篇文章用「水井三寶」(烏龜、白馬、姻緣花)為主題,展示了 Python 類的七大核心技術:
- 封裝:保護烏龜的能量值。
- 繼承:白馬繼承寶物基類的吉祥能力。
- 多型:烏龜和姻緣花用不同方式「說話」。
- 類與實例屬性:共享「水井吉祥」,每個寶物有獨特名稱。
- 特殊方法:姻緣花自訂顯示和加法。
- 類方法與靜態方法:白馬的召喚和速度計算。
- 屬性管理:控制烏龜年齡的存取。
範例一:封裝(Encapsulation)
封裝保護物件內部資料,限制外部直接存取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Turtle: def __init__(self, name): self.__energy = 100 # 私有屬性:能量值 self.name = name def get_energy(self): # 公開方法存取 return self.__energy def use_energy(self, amount): if amount > 0: self.__energy -= amount return f"{self.name} 使用 {amount} 能量,剩餘 {self.__energy}" return "無效的能量消耗!" # 測試 t = Turtle("烏龜") print(t.get_energy()) # 輸出: 100 print(t.use_energy(20)) # 輸出: 烏龜 使用 20 能量,剩餘 80 # print(t.__energy) # 錯誤!無法直接存取私有屬性 |
執行結果:
100 烏龜 使用 20 能量,剩餘 80
解釋:__energy 是私有屬性,外部無法直接存取,只能透過 get_energy 和 use_energy 方法控制,展現封裝保護資料的能力。
範例二:繼承(Inheritance)
繼承讓子類重用父類的屬性和方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Treasure: def __init__(self, name): self.name = name def bless(self): return f"{self.name} 帶來吉祥!" class WhiteHorse(Treasure): # 繼承 Treasure def gallop(self): # 子類專屬方法 return f"{self.name} 飛馳千里!" # 測試 horse = WhiteHorse("白馬") print(horse.bless()) # 輸出: 白馬 帶來吉祥!(來自父類) print(horse.gallop()) # 輸出: 白馬 飛馳千里!(子類專有) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Treasure: def speak(self): pass # 抽象方法,子類需實現 class Turtle(Treasure): def speak(self): return "烏龜:穩重長壽!" class MarriageFlower(Treasure): def speak(self): return "姻緣花:愛情綻放!" # 測試 treasures = [Turtle(), MarriageFlower()] for t in treasures: print(t.speak()) # 輸出: 烏龜:穩重長壽! 和 姻緣花:愛情綻放! |
執行結果:
類屬性共享於所有實例,實例屬性獨立於每個物件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Treasure: shared_blessing = "水井吉祥" # 類屬性 def __init__(self, name): self.name = name # 實例屬性 def describe(self): return f"{self.name} 擁有 {Treasure.shared_blessing}" # 測試 t1 = Treasure("烏龜") t2 = Treasure("白馬") print(t1.describe()) # 輸出: 烏龜 擁有 水井吉祥 print(t2.describe()) # 輸出: 白馬 擁有 水井吉祥 Treasure.shared_blessing = "三寶輝煌" # 修改類屬性 print(t1.describe()) # 輸出: 烏龜 擁有 三寶輝煌 |
執行結果:
烏龜 擁有 水井吉祥 白馬 擁有 水井吉祥 烏龜 擁有 三寶輝煌
解釋:shared_blessing 是類屬性,所有實例共享,修改它會影響所有物件;name 是實例屬性,各物件獨立。
範例五:特殊方法(Magic/Dunder Methods)
特殊方法自訂物件行為,如字串表示或運算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class MarriageFlower: def __init__(self, beauty): self.beauty = beauty def __str__(self): # 自訂字串表示 return f"姻緣花 美麗值: {self.beauty}" def __add__(self, other): # 自訂加法 total_beauty = self.beauty + other.beauty return MarriageFlower(total_beauty) # 測試 f1 = MarriageFlower(10) f2 = MarriageFlower(20) print(f1) # 輸出: 姻緣花 美麗值: 10 combined = f1 + f2 print(combined) # 輸出: 姻緣花 美麗值: 30 |
執行結果:
姻緣花 美麗值: 10 姻緣花 美麗值: 30
解釋:__str__ 自訂 print 輸出;__add__ 讓 + 運算符合併兩朵姻緣花的美麗值,展示特殊方法的靈活性。
範例六:類方法與靜態方法(Class Methods and Static Methods)
類方法操作類本身,靜態方法獨立於類和實例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class WhiteHorse: @classmethod def summon(cls, name): # 類方法 return cls() @staticmethod def calculate_speed(distance, time): # 靜態方法 return f"白馬速度:{distance / time} 公里/小時" def __init__(self): self.name = "白馬" # 測試 horse = WhiteHorse.summon("白馬") # 類方法創建實例 print(WhiteHorse.calculate_speed(100, 2)) # 輸出: 白馬速度:50.0 公里/小時 |
執行結果:
屬性裝飾器將方法偽裝成屬性,控制存取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class Turtle: def __init__(self, age): self._age = age # 保護屬性 @property def age(self): # getter return self._age @age.setter def age(self, value): # setter if value < 0: raise ValueError("烏龜年齡不能為負!") self._age = value # 測試 t = Turtle(50) print(t.age) # 輸出: 50 t.age = 100 # 使用 setter 修改 print(t.age) # 輸出: 100 # t.age = -10 # 會拋出錯誤 |
執行結果:
50 100
解釋:@property 讓 _age 像屬性一樣存取;@age.setter 控制賦值,確保年齡不為負數。
