哥布林學 Python 物件導向 (OOP)

物件導向 (OOP) 是一種程式設計的規範 (paradigm),遵循之後有助於寫出更容易管理、容易維護,且容易閱讀的程式碼。而 Python 本身借鏡了許多 OOP 的概念,雖然沒有像 Java 那樣嚴格,但諸如 flask、Pygame 等等熱門框架也以 OOP 為主旋律,多去了解絕對不吃虧。 一切都由物件組成 OOP 的核心概念其實很簡單,那就是將我們日常生活中的人事物「建模」成一個一個又一個的物件,而每個物件當中會包含: 屬性 (attribute):類似於字典 (dictionary) 的 key-value 資料 方法 (method):函式,沒錯,就是函式 舉個例子,假設我們用一個物件來代表「人」這個概念,那該物件裡面可能會有以下屬性: 姓名 年齡 住址 興趣 職業 除此之外,該物件也會包含人的行為,這些行為便是所謂的方法,所以物件將包含以下函式: 走路 跑步 吃飯 嗚啦 先有藍圖,才有物件 想像你是全知全能的天神,某日心血來潮想為世界增添趣味,於是決定創造名為哥布林的生物,讓他們自生自滅繁衍生息。你給自己泡了杯咖啡,創造了一隻、兩隻、三隻哥布林,漸漸發現如此單調重複的工作 超 . 級 . 無 . 聊,於是靈機一動,先打造了一套哥布林模型,注入神力讓模型依照既定規則自動生成哥布林…… 這基本上就是我們建立物件的方式。Python 透過 class 關鍵字讓我們先產出物件的藍圖,後續依循藍圖去建立單一物件。所以物件的屬性、方法都要在 class 當中先定義好。 class Goblin: health = 5 damage = 3 Xavier = Goblin() print(Xavier.health) # 5 可以注意到若要從物件中提取屬性值,語法為 <object_name>.<attribute>。 相較於 class 是物件的藍圖,我們依據藍圖所生成的物件則是 instance,實體。真實的資料會包裹在實體中。 為物件增添函式 - method 前面提過綁定在 class 當中的函式被稱之為方法。方法和一般函式最大的差異,在於它能夠直接存取該物件的屬性。 ...

二月 16, 2025

初探 Python 字典 (Dictionary)

什麼是字典 (Dictionary)? 在 Python 中,字典用來儲存 key -> value 組合的資料,和 JavaScript 的物件 (objects) 非常類似。字典使用 {} 來包裹住資料,每個鍵 (key) 都會對應到一個值 (value): goblin = { "name": "Xavier", "age": 28, "pet": "Mimiball" } 不要重複 key 列表利用索引 (index) 來辨別資料,而字典則是依靠鍵 (key)。所以實作上我們不應該在字典中重複使用 key,如果不信邪,你會發現原先的值被覆寫過去了! goblin = { "name": "Xavier", "name": "Neo-Xavier" "age": 28, "pet": "Mimiball" } 上面範例中,哥布林的名字從 Xavier 變成了 Neo-Xavier,因為兩筆資料的 key 都是 name,而後面的資料覆寫了前面一筆 key 相同的資料。 操作字典中的資料 基本上不脫離取、增、刪、變四大操作,下面逐一說明。 提取字典中的資料 使用 [] 來提取字典中的資料。前面提過字典是靠 key 來辨別每一筆資料,所以我們需要在 [] 帶入特定資料的 key,而且要用字串的方式帶入,也就是前後加上 ""。 goblin = { "name": "Xavier", "age": 28, "pet": "Mimiball" } print(goblin["name"]) 新增字典資料 實務上我們常常會先建立一個空字典,然後依照商業邏輯陸續新增動態資料到字典中。而新增資料到字典的方式和提取資料大同小異,一樣使用 [key_name] 的模式即可。 ...

一月 25, 2025

初探 Python 元組 (Tuples)

什麼是元組 (Tuples)? 元組是 Python 其中一種資料集合的型別,具有以下兩種特色: 資料有序排列,可用索引提取資料 資料無法變更 所以基本上,我們可以將元組看作是固定長定、無法變更的列表。 在建立列表時,我們通常不會置入不同型別的資料,但這在元組中不成問題,因為元組的長度是固定的,所以能輕易追蹤哪個索引儲存哪種型別的資料。 和列表的 [] 不同,元組需要使用 () 來建立: my_tuple = ("this is a tuple", 45, True) print(my_tuple[0]) # this is a tuple print(my_tuple[1]) # 45 print(my_tuple[2]) # True 元組通常用來儲存少量、固定不變的資料。 元組和列表混用 由於元組本身就是資料的容器,所以我們可以將多個元組儲存在列表當中。 語法上和一般資料相同,用半形逗號區隔不同的元組,然後每個元組在列表中都有自己的索引。也就是說,當我們要提取列表中的元組資料,第一個索引代表要選取哪個元組,而第二個索引代表要選取該元組中哪筆資料。 my_tuples = [("this is the first tuple in the list", 45, True),("this is the second tuple in the list", 21, False)] print(my_tuples[0][0]) # this is the first tuple in the list print(my_tuples[0][1]) # 45 print(my_tuples[1][0]) # this is the second tuple in the list print(my_tuples[1][2]) # False 開箱元組 Tuple Unpacking 好像網路上有人翻譯成元組拆包,但我自己是習慣用「開箱元組」來指稱,因為開箱聽起來比較開心。 ...

一月 23, 2025

初探 Python 列表 (List) - 續

不靠索引也能提取列表資料 如果不需要更新列表中的資料,我們其實可以用更精簡的語法去遞迴列表。in 關鍵字負責宣告 friend 變數,儲存每一次遞迴所提取的列表資料: friends = ["Cute Goblin", "Big Goblin", "Small Goblin", "Taipei Goblin"] for friend in friends: print(friend) # Cute Goblin # Big Goblin # Small Goblin # Taipei Goblin 這種簡潔的語法在尋找列表資料時尤其方便,因為我們只在乎列表的資料值,索引直接捨棄也不用在意,像極了哥布林的愛情: def contains_small_goblin(friends): found = False for friend in friends: if friend == "Small Goblin": found = True return found 尋找最大數 這算是個小技巧(?),如果我們想從列表中找出最大數,可以先將初始值宣告為float("-inf"),這樣便能確保列表中每個數字都比它更大。接下來用遞迴陸續找出更大的數值,然後取代它就可以了。 def find_max(nums): max_so_far = float("-inf") for num in nums: if num > max_so_far: max_so_far = num return max_so_far 同理,若是要找出最小數,將初始值變數宣告為float("inf")即可。 切割列表 我們可以用 : 切割出列表的特定區段,那回傳的會是一個新的列表。除了從哪裡開始、到哪裡結束之外,我們還能指定中間要跳過幾筆資料 (step)。 ...

一月 20, 2025

初探 Python 列表 (List)

什麼是列表? 程式語言通常都會有負責組織、儲存多筆資料的資料型別。在 JavaScript 和 Golang 中,這種資料型別被稱為陣列 (array),而 Python 則是列表 (list)。 Python 中的列表用 [...] 宣告,每項資料中間以半形逗號區隔: friends = ["Cute Goblin", "Big Goblin", "Small Goblin", "Taipei Goblin"] 上面的列表中清一色都是字串,但我們其實可以在列表中加入各種型別的資料。 若資料量持續增加,我們可以將每筆資料一行一行拆開,讓程式碼更容易閱讀。畢竟很多東西,不是越長就越好: friends = [ "Cute Goblin", "Big Goblin", "Small Goblin", "Taipei Goblin" ] goblin_age = [ 25, 18, 55 ] 用索 (index) 提取列表中的資料 首先我們要知道在程式的世界,通常都是從 0 開始計數的,而非日常生活中直覺的 1。 列表中每一筆資料都有其索引 (index),也就是該筆資料在列表中的位置。再提醒一次,務必要從 0 開始算起。 friends = ["Cute Goblin", "Big Goblin", "Small Goblin", "Taipei Goblin"] 以上述列表為例,每筆資料的索引如下: 0:Cute Goblin 1:Big Goblin 2:Small Goblin 3:Taipei Goblin 再舉個例子,索引 1 等於列表當中第二筆資料。 ...

一月 19, 2025

迴圈 - 以 Python 為例

為什麼要有迴圈? 原因只有一個,那就是人類很懶,假設今天要輸出 100 萬筆資料,我們需要一筆一筆手刻出來嗎?在被主管開除之前,我們應該會先無聊到開始裸奔吧。 這個時候善用迴圈,用一組程式碼就能搞定大量的重複工作: for i in range(0, 1_000_000): print(i) 拆解 for 迴圈運作流程 上面以 for 關鍵字起頭的迴圈被稱為 for 迴圈,除了 Python 之外,Golang、JavaScript 等等眾多程式語言也都有類似的語法。本篇文章就以 Python 為例,拆解 for 迴圈的運作流程。 迴圈從 i 等於 0 啟動 -> i in range(0) 檢查若 i 不少於 1,000,000 就跳出迴圈運作 -> range(0, 1_000_000),否則繼續執行以下動作: 列印出 i 變數 -> print(i) i 變數值加一 (range 預設會加一) 回到第二步驟檢查 i 是否不少於 1,000,000 最後我們會看到 0 ~ 999,999 列印出來。 在 Python 中,range(a, b) 會包含 a 但不包含 b。所以 range(0, 1_000_000) 才不會列印出 1,000,000。 ...

一月 18, 2025

作用域 - 以 Python 為例

什麼是作用域? 作用域 (Scope) 是指變數或函示名稱可以被使用的範圍。我自己是想像成結界,外面的世界無法接觸、取用到結界內的萬事萬物。 舉例來說,當我們在函式中建立一個變數,包含給函示參數,那這些資料就無法在函示的作用域範圍之外使用,會跑出該變數沒有定義的錯誤。 def add(x, y): return x + y result = add(2, 6) print(x) # ERROR! "name 'x' is not defined" 上述範例中,x 和 y 都是 add 函式的參數,因此只能在 add 函式作用域範圍內被使用。我們在作用域之外嘗試列印 x,Python 的編譯器會跳出 x 沒有被定義的錯誤警告。 全域作用域 我們知道函式中所定義的變數和參數,是無法在函式作用域以外被使用的。但如果今天有多個函式都要用同一組變數該怎麼辦呢?我們可以在全域環境中定義變數,這樣每個函式都能夠取用該變數了。 以結界來比喻,我覺得就像結界內的人可以把外面世界的物品拉進去,但外部世界的人無法看透結界內發生什麼事情,自然也就無法取用結界內的物品了。 outside_stuff = "pull me in baby!" def pull_outside_stuff_into_function_scope(target): return outside_stuff + " - success" print(pull_outside_stuff(outside_stuff)) 上述範例中,pull_outside_stuff_into_function_scope 最終會成功回傳 pull me in baby! - success。因為 outside_stuff 變數是在權域作用域 (global scope) 定義的,所以能夠被函式拉到函式作用域當中使用。

一月 15, 2025