Python中self用法示例詳解
前言
在 Python 中,self 并不是語言關鍵字,而是實例方法中第一個參數(shù)的約定名稱,指向調(diào)用該方法的實例對象。它的顯式存在集中體現(xiàn)了 Python 的核心設計哲學:顯式優(yōu)于隱式、一切皆對象,以及簡潔一致的調(diào)用模型。
一、self 的本質(zhì)是什么
首先要知道的是,self 不是 Python 的關鍵字,也沒有任何特殊語法含義。它只是實例方法中第一個參數(shù)的慣用名稱,用于表示“當前對象的實例引用”。
例如:
class Dog: def bark(self): print("Woof!")當我們執(zhí)行:
d = Dog()d.bark()
Python 實際上在內(nèi)部做了如下調(diào)用:
Dog.bark(d)
也就是說,self 就是調(diào)用該方法的對象實例 d。因此,bark() 方法能通過 self 訪問對象的屬性和其他方法。
二、為什么必須顯式寫出 self
很多面向?qū)ο笳Z言(如 Java、C++)中有一個隱藏參數(shù) this,它在方法中自動存在。Python 沒有這樣做,原因在于它的“一切皆對象”哲學:方法本質(zhì)上就是函數(shù)對象,只是存放在類的命名空間中。
Python 不希望讓“方法”成為一種特殊語法,而是通過普通函數(shù)與對象綁定的機制來實現(xiàn)方法調(diào)用。這種設計讓函數(shù)、類、實例三者的關系更透明、更靈活。
Python 不會自動注入“實例引用”,必須顯式聲明第一個參數(shù),社區(qū)約定俗成地命名為 self。
這使得方法調(diào)用規(guī)則簡單且一致:任何函數(shù)若綁定到實例上,其第一個參數(shù)都會接收實例對象。
三、方法的綁定機制:self 如何被傳入
要理解 self,首先需要了解方法在 Python 中是如何被綁定的。
當我們通過 實例.方法 的方式訪問一個方法時,Python 會執(zhí)行以下步驟:
1、在實例所屬的類中查找該方法對應的函數(shù)對象。
2、如果找到該函數(shù)對象 f,則觸發(fā)其 __get__() 方法(這是通過描述符機制實現(xiàn)的)。
3、__get__() 方法會返回一個綁定方法(bound method) 對象,該對象內(nèi)部保存了當前實例的引用。
4、當我們調(diào)用這個綁定方法時,Python 會自動將保存的實例作為第一個參數(shù)(即 self)傳入原函數(shù)。
示例說明:
class A: def show(self, x): print(self, x) a = A()a.show(10)
上述調(diào)用實際上等價于:
A.show(a, 10)
也就是說:
??通過實例訪問方法時,會得到一個已綁定實例的“綁定方法”,調(diào)用時自動傳入 self。
??通過類訪問方法時,得到的仍是一個普通函數(shù),調(diào)用時需要顯式傳入實例作為 self。
四、三種方法綁定的比較
Python 中存在三種類型的方法綁定方式:
方法類型 | 裝飾器 | 第一個參數(shù) | 隱式綁定對象 | 用途 |
|---|---|---|---|---|
實例方法 | (無) | self | 實例 | 訪問或修改實例狀態(tài) |
類方法 | @classmethod | cls | 類對象 | 操作類本身(如工廠方法) |
靜態(tài)方法 | @staticmethod | (無) | 無 | 工具函數(shù),不依賴實例或類 |
示例:
class Example: def instance_method(self): print("實例方法", self)
@classmethod def class_method(cls): print("類方法", cls)
@staticmethod def static_method(): print("靜態(tài)方法")調(diào)用方式:
obj = Example()obj.instance_method() # 自動傳入實例Example.class_method() # 自動傳入類Example.static_method() # 不傳入任何對象
五、self 在繼承與多態(tài)中的作用
self 永遠指向?qū)嶋H調(diào)用該方法的對象。即使方法定義在父類中,被子類繼承后調(diào)用時,self 仍然指向子類實例。
示例:
class Animal: def speak(self): print("Animal speaking:", type(self).__name__)
class Cat(Animal): pass
class Dog(Animal): pass
Cat().speak() # Animal speaking: CatDog().speak() # Animal speaking: DogAnimal.speak() 方法內(nèi)部訪問的 self,在運行時綁定為 Cat 或 Dog 實例,這就是多態(tài)(polymorphism)的基礎。
六、super() 與 self 的協(xié)作
在繼承中使用 super() 時,Python 會根據(jù)方法解析順序(MRO)找到父類的方法,但 self 不會變。
class Base: def show(self): print("Base:", self)
class Sub(Base): def show(self): print("Sub before") super().show() # 調(diào)用 Base.show(self) print("Sub after")
s = Sub()s.show()輸出:
Sub beforeBase: <__main__.Sub object ...>Sub after
注意:super().show() 雖然調(diào)用了父類方法,但 self 仍然是 Sub 實例。
七、常見錯誤與誤區(qū)
(1)方法定義中遺漏 self 參數(shù)
class Bad: def func(): print("missing self")
Bad().func() # TypeError: Bad.func() takes 0 positional arguments but 1 was given異常原因:通過實例調(diào)用方法時,Python 會自動將實例本身作為第一個參數(shù)傳入,但該方法定義沒有預留接收該參數(shù)的位置。
(2)誤以為 self 是固定關鍵字
實際上,self 只是約定俗成的參數(shù)名,可以使用任意名稱替代:
class A: def f(this): print(this)
但這樣做違反了 Python 社區(qū)的編碼規(guī)范,會嚴重損害代碼的可讀性和一致性。按照 PEP 8 約定,始終使用 self 表示實例方法的第一個參數(shù),使用 cls 表示類方法的第一個參數(shù)。
(3)混淆類屬性與實例屬性
class Counter: count = 0 # 這是類屬性,所有實例共享
def __init__(self): self.count += 1 # 這里實際創(chuàng)建了一個新的實例屬性!如需修改類屬性,應顯式引用類名:
Counter.count += 1 # 正確修改類屬性
八、self 的設計哲學
從語言設計的角度看,self 的設計體現(xiàn)了 Python 的幾項核心理念。
(1)顯式優(yōu)于隱式(Explicit is better than implicit)
self 作為方法的第一個參數(shù)明確寫出,清晰地表明了實例的傳遞過程,避免了像其他語言中隱藏的 this 指針所帶來的隱式行為。
(2)一切皆對象
在 Python 中,方法本身也是對象。具體來說,是綁定到類中的函數(shù)對象。方法的綁定過程通過描述符協(xié)議實現(xiàn),而非特殊的語法規(guī)則,這體現(xiàn)了 Python 對象模型的一致性。
(3)簡潔一致的調(diào)用模型
無論是 obj.method() 還是 Class.method(obj),本質(zhì)上都是將實例作為第一個參數(shù)傳遞給函數(shù)。這種設計消除了方法調(diào)用與函數(shù)調(diào)用之間的概念差異,保持了語義的一致性。
小結(jié)
在 Python 中,self 是實例方法中第一個參數(shù)的約定名稱。通過 self,實例方法能夠訪問和修改對象的狀態(tài),并天然支持繼承與多態(tài)特性。即使在通過 super() 調(diào)用父類方法時,self 依然正確地指向最初發(fā)起調(diào)用的實際對象。
因此,深入理解 self 不僅有助于掌握方法綁定的底層機制,更是透徹理解 Python 面向?qū)ο缶幊淘O計思想的重要基石。
到此這篇關于Python中self用法示例詳解的文章就介紹到這了,更多相關Python self用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
如何使用 Python 讀取 Excel 數(shù)據(jù)
這篇文章主要介紹了使用 Python 讀取 Excel 數(shù)據(jù)的詳細教程,通過 pandas 和 openpyxl,你可以輕松讀取 Excel 文件,并進行各種數(shù)據(jù)處理操作,pandas 更適合快速、簡單的數(shù)據(jù)分析,而 openpyxl 則適合需要對 Excel 文件進行更深入控制的場景,需要的朋友可以參考下2025-04-04
python使用Celery構(gòu)建異步任務隊列提高服務器吞吐量及響應速度
這篇文章主要介紹了python使用Celery構(gòu)建異步任務隊列提高服務器吞吐量及響應速度實例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01
Python和Matlab實現(xiàn)蝙蝠算法的示例代碼
蝙蝠算法是一種搜索全局最優(yōu)解的有效方法,本文主要介紹了Python和Matlab實現(xiàn)蝙蝠算法的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03

