Python 類別與物件(Class and Object)
這篇 Python class 教學將帶你進入物件導向(OOP):把「資料」與「操作資料的函式」包在一起的程式設計方式。其實你早就在用物件了——字串、List、Dictionary 都是物件,它們的方法(append、split)就是包在類別裡的函式。現在輪到你自己定義。
| 名詞 | 意義 | 比喻 |
|---|---|---|
| 類別(class) | 物件的設計圖 | 「學生」這個概念 |
| 物件(object/instance) | 依設計圖做出的實體 | 小明、小華這些具體的學生 |
| 屬性(attribute) | 物件身上的資料 | 姓名、成績 |
| 方法(method) | 物件能做的動作 | 自我介紹、計算平均 |
定義類別與建立物件
class Student:
def __init__(self, name, score):
self.name = name # 把參數存成物件的屬性
self.score = score
def introduce(self):
print(f"我是 {self.name},考了 {self.score} 分")
s1 = Student("小明", 85) # 建立物件(會自動呼叫 __init__)
s2 = Student("小華", 92)
s1.introduce()
s2.introduce()
print(s1.score + s2.score)
執行輸出:
我是 小明,考了 85 分
我是 小華,考了 92 分
177
__init__ 與 self 是什麼
最讓初學者困惑的兩個東西,一次講清楚:
__init__(建構式):建立物件時自動執行的方法,負責初始化屬性。Student("小明", 85) 的參數就是傳給它。
self(物件自己):方法的第一個參數,代表「呼叫這個方法的那個物件」。s1.introduce() 時,self 就是 s1;s2.introduce() 時就是 s2——所以同一個方法能印出不同人的名字。定義方法時要寫 self,呼叫時不用傳,Python 自動帶入。
屬性可以隨時讀取與修改
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
s = Student("小明", 85)
print(s.score)
s.score = 90 # 直接修改屬性
print(s.score)
執行輸出:
85
90
方法之間互相呼叫
方法內用 self.方法名() 呼叫同物件的其他方法:
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
def deposit(self, amount):
self.balance += amount
self.show() # 呼叫自己的另一個方法
def show(self):
print(f"{self.owner} 餘額:{self.balance}")
acc = BankAccount("小明", 100)
acc.deposit(500)
執行輸出:
小明 餘額:600
類別屬性 vs 實例屬性
定義在 __init__ 外層的是「類別屬性」,所有物件共用——這是個常見陷阱:
class Student:
school = "中山高中" # 類別屬性:大家共用
def __init__(self, name):
self.name = name # 實例屬性:各自獨立
s1 = Student("小明")
s2 = Student("小華")
print(s1.school, s2.school)
Student.school = "建國中學" # 改類別屬性,所有物件都變
print(s1.school, s2.school)
執行輸出:
中山高中 中山高中
建國中學 建國中學
可變型別(List、dict)千萬不要當類別屬性,會發生跟「可變預設參數」一樣的共用災難。
常見錯誤
1. TypeError: introduce() takes 0 positional arguments but 1 was given
定義方法時忘了寫 self。Python 呼叫 s1.introduce() 時會自動把 s1 傳進去,方法卻沒有參數可以接。
2. AttributeError: ‘Student’ object has no attribute ‘xxx’
存取不存在的屬性:拼錯字,或該屬性只在某些條件下才被建立。屬性盡量都在 __init__ 裡初始化。
3. 忘記加括號建立物件
s = Student 只是把類別本身指給變數,s = Student("小明", 85) 才是建立物件。前者之後呼叫方法會出現奇怪的 TypeError。
總結
class 是設計圖、物件是實體;__init__ 負責初始化、self 代表物件自己(定義要寫、呼叫不用傳);實例屬性各自獨立、類別屬性全體共用(可變型別別放這)。下一篇學繼承——讓類別之間共享與擴充功能。