FacebookLinkedInTweet更新日期: 2024 年 11 月 18 日
本文為 python 物件導向系列文:第一篇
深入理解 Python 中的 self 與物件導向原理 👈所在位置
初學者指南:深入了解 Python 的 init 方法
理解 Python 中的 str 與 repr 方法
初學者指南:深入了解 Python 繼承
初學者指南:深入了解 Python 方法覆寫與 super()
初學者指南:深入了解 Python 中的多重繼承與鑽石問題
在 Python 的物件導向編程 (OOP) 中,self 是一個關鍵概念,負責將類別的實例與方法綁定在一起。
初學者經常會對 self 的用途感到疑惑,尤其是為什麼在定義類別方法時,需要將 self 作為第一個參數。
本文將透過範例逐步解析 self 的作用與原理,幫助你掌握 Python 的物件導向設計。
前言
當我們定義一個類別並試圖調用其方法時,可能會遇到一個令人困惑的錯誤提示:
class Cat:
def hi():
print('hi')
kitty = Cat()
kitty.hi()
執行上述程式時,會出現以下錯誤:
TypeError: Cat.hi() takes 0 positional arguments but 1 was given
為什麼會有多出來的參數?為什麼需要在方法中加入 self?
接下來,我們將深入探討這些問題。
錯誤的原因:Python 的方法調用原理
在 Python 中,當你透過實例調用類別的方法時,例如 kitty.hi(),Python 會自動將實例 kitty 傳遞給方法作為第一個參數。
上述程式的問題在於,方法 hi() 並沒有為這個自動傳入的參數保留位置。
因此,修正後的程式應該定義一個參數來接收這個實例,並依照慣例命名為 self:
class Cat:
def hi(self): # 第一個參數用於接收實例
print('hi')
kitty = Cat()
kitty.hi()
執行結果:
hi
self 的作用與必要性
self 是指向實例本身的參數,它讓方法能夠訪問和操作該實例的屬性與行為。
連結實例與方法
透過 self,Python 可以將方法綁定到具體的實例上。
當你調用 kitty.hi() 時:
Python 自動將 kitty 傳遞給方法 hi 作為第一個參數 self。
訪問實例屬性
self 允許我們在方法內訪問和修改實例屬性。
例如:
class Cat:
def __init__(self, name):
self.name = name # 定義實例屬性
def greet(self):
print(f"Meow! 我是 {self.name}")
kitty = Cat(name="Kitty")
kitty.greet()
執行結果:
Meow! 我是 Kitty
self.name使用 self 訪問屬性,確保每個實例都有自己的 name,而不會與其他實例混淆。
為什麼 self 必須顯式定義?
與其他語言(例如 JavaScript)的隱式關鍵字 this 不同,Python 採用了顯式的方式來處理實例參考。
這樣的設計有幾個好處:
清晰性定義方法時,第一個參數 self 明確表達了這是實例方法,對開發者更直觀。
一致性Python 的一切皆為對象,包括方法。因此,所有方法(無論是否是類別方法)都以顯式的參數列表來表達。
與其他語言的比較
1. JavaScript 的 this
在 JavaScript 中,this 的值根據調用方式而變化,可能指向不同的物件。
例如:
class Cat {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Meow! 我是 ${this.name}`);
}
}
const kitty = new Cat("Kitty");
kitty.greet(); // 正常執行
const greetFn = kitty.greet;
greetFn(); // 出錯,this 指向全域物件
JavaScript 的 this 依賴執行環境,容易出現指向錯誤的問題。
Python 的 self
Python 的 self 必須顯式傳遞,因此不會出現類似於 JavaScript 的 this 指向問題。
例如:
class Cat:
def __init__(self, name):
self.name = name
def greet(self):
print(f"Meow! 我是 {self.name}")
kitty = Cat(name="Kitty")
kitty.greet() # 永遠正確地使用 self
self 明確綁定到實例,消除了模糊性。
總結
在 Python 中,self 是物件導向編程中不可或缺的部分:
它負責將方法與實例綁定,確保每個實例有自己的屬性與行為。
它提供了一種清晰且一致的方式來訪問實例數據,避免了像 JavaScript 那樣的指向問題。
雖然顯式傳遞 self 可能看起來麻煩,但它是 Python 設計中對清晰性和一致性的一種追求。
理解並掌握 self 的使用,將使你在物件導向設計中如魚得水。