甲居工作室

11.Python 類別 (Class)

日期:2024/04/09

11.Python 類別 (Class)

『物件導向程式設計』(Object-oriented programming, OOP) 是一種程式開發的概念,以物件的概念來解決問題。

封裝、繼承、多型為物件導向的三大特性,本章節會略提此概念,建議後續抽空學習物件導向程。

11.1 類別 (Class)

在 Python 中,類別 (Class) 是用來創建物件又稱實例 (Instance)的藍圖或模板。類別定義了物件的屬性 (資料) 和方法 (函式),它們描述了物件的特徵和行為。通過定義類別,我們可以創建多個具有相同屬性和方法的物件。

基本語法

  1. class ClassName:
  2. # 屬性
  3. # 方法
  4. pass
  5. className = ClassName()
  • 類別名稱為 ClassName ,通常使用大寫做開頭。
  • 建立物件時習慣將開頭的大寫轉小寫表示。
  • 屬性:以變數的形式呈現。
  • 方法:以函式的形式呈現。
  1. class Rectangle:
  2. width = 1
  3. height = 1
  4. def area(self):
  5. return self.width * self.height
  6. rectangle = Rectangle() # 實例化
  7. rectangle.height = 2 # 更改物件屬性
  8. print(rectangle.area()) # 執行方法
  9. # 2

物件的初始設定

當 class 定義了__init__() method,class 實例化會為新建的 class 實例自動調用__init__()。在產生物件時可以一併設定屬性:

  1. class Rectangle:
  2. def __init__(self, width, height):
  3. self.width = width
  4. self.height = height
  5. def area(self):
  6. return self.width * self.height
  7. rectangle = Rectangle(2, 6) # 實例化
  8. rectangle.height = 3 # 更改物件屬性
  9. print(rectangle.area()) # 執行方法
  10. # 6

Method 物件

我們一樣使用 Rectangle 類別做示範:

  1. area1 = rectangle.area
  2. print(area1())

這次我們呼叫方法時沒有加上任何參數在此為(),表示此時函式尚未執行,等需要時在加上參數。

具體的應用場景可能為,在程式碼的某些部分需要指定執行的函數,因此,先定義一個函數引用,然後在需要的時候再呼叫它並傳入參數。

11.2 繼承 (Inheritance)

基本語法

  1. class ClassName(ParentClass):
  2. # 屬性
  3. # 方法
  4. pass
  • ParentClass:繼承類別的名稱 (稱為「父類別」,Parent class)
  • 可多重繼承: class ClassName(ParentClass1, ParentClass2)

函式

我們先假設有以下兩個 Class:

  1. class A:
  2. pass
  3. class B(A):
  4. pass
  • isinstance(object, classinfo):用於判斷類別及物件的關係。
    1. obj = B()
    2. print(isinstance(obj, B)) # True
    3. print(isinstance(obj, A)) # True
  • issubclass(classinfo1, classinfo2):用於判斷類別是否為另一類別的子關係。
    1. print(issubclass(B, A)) # True

11.3 Override (覆寫)

Override (覆寫) 是指子類別重新定義 (覆蓋) 父類別中的方法,使該方法擁有不同於父類別的行為。

  1. class Parent:
  2. def show(self):
  3. print("父類別的 show 方法")
  4. class Child(Parent):
  5. def show(self):
  6. print("子類別的 show 方法")
  7. obj = Child()
  8. obj.show() # 子類別的 show 方法

11.4 Overload (多載)

Python 不直接支援方法多載。方法多載是指在同一個類別中定義多個同名方法,但這些方法的參數類型或數量不同。在 Python 中,由於 Python 的動態特性,同一個類別中只能存在一個方法名相同的方法,即後面定義的方法會覆蓋前面定義的方法,而不會產生方法多載。

當然這只是意義上的不行,我們可以透過一些方式達成相似的結果。

方法 1:透過參數的控制,是否還記得位置參數、關鍵字參數、默認參數、*args 與 **kwargs

  1. def greet(**kwargs):
  2. if 'name' in kwargs:
  3. print('Hello, ' + kwargs['name'])
  4. else:
  5. print('Hello, World')
  6. greet() # 輸出: Hello, World
  7. greet(name="Alice") # 輸出: Hello, Alice

方法 2:透過multipledispatch 套件中的裝飾器@dispatch(),目前先看過去即可後續章節會介紹裝飾器。

  1. from multipledispatch import dispatch
  2. @dispatch(int, int)
  3. def add(x, y):
  4. return x + y
  5. @dispatch(float, float)
  6. def add(x, y):
  7. return x + y
  8. @dispatch(str, str)
  9. def add(x, y):
  10. return x + y
  11. print(add(1, 2)) # 3
  12. print(add(1.5, 2.5)) # 4.0
  13. print(add('Hello, ', 'World')) # Hello, World

當然還有其他方式及套件歡迎自行探索。

11.5 Polymorphism (多型)

多型是指相同的操作或函式在不同的物件上可以有不同的行為。具體來說,多型允許將父類別的引用指向子類別的物件,從而以統一的方式使用不同類別的物件。多型通過對繼承、覆寫等機制的合理應用來實現。

  1. class Animal:
  2. def makeSound(self):
  3. pass
  4. class Fox(Animal):
  5. def makeSound(self):
  6. return "叮叮叮"
  7. class Cat(Animal):
  8. def makeSound(self):
  9. return "喵喵"
  10. class Mushroom(Animal):
  11. def makeSound(self):
  12. return "蘑菇 蘑菇"
  13. def animalSound(animal):
  14. print(animal.makeSound())
  15. fox = Fox()
  16. cat = Cat()
  17. mushroom = Mushroom()
  18. animalSound(fox) # 叮叮叮
  19. animalSound(cat) # 喵喵
  20. animalSound(mushroom) # 蘑菇 蘑菇

延伸閱讀

12. Python 撰寫準則

想必大家上一章節頭腦都快要炸裂了吧? 本章談論輕鬆一點的事情。

Read more

13.Python 裝飾器 (Decorator)

使用裝飾器可以幫助你避免代碼的重複,從而提高了代碼的重用性和可擴展性。

Read more