和類屬性可細分為類屬性和執行個體屬性一樣,類中的方法也可以有更細緻的劃分,具體可分為類方法、執行個體方法和靜态方法,本節将詳細介紹這 3 種類方法的特點和用法。
Python類執行個體方法
通常情況下,在類中定義的方法預設都是執行個體方法。前面章節中,我們已經定義了不隻一個執行個體方法。不僅如此,類的構造方法理論上也屬于執行個體方法,隻不過它比較特殊。
例如:
class Person :
#類構造方法,也屬于執行個體方法
def __init__(self, name = 'Charlie', age=8):
self.name = name
self.age = age
# 下面定義了一個say執行個體方法
def say(self, content):
print(content)
執行個體方法最大的特點就是,它最少也要包含一個 self 參數,用于綁定調用此方法的執行個體對象。執行個體方法通常會用類對象直接調用,當然也可以用類名調用,例如:
#建立一個類對象
person = Person()
#類對象調用執行個體方法
person.say("類對象調用執行個體方法")
#類名調用執行個體方法,需手動給 self 參數傳值
Person.say(person,"類名調用執行個體方法")
運作結果:
類對象調用執行個體方法
類名調用執行個體方法
Python類方法
Python 類方法和執行個體方法相似,它最少也要包含一個參數,隻不過,類方法中通常将其命名為 cls,且 Python 會自動将類本身綁定給 cls 參數(而不是類對象)。是以,在調用類方法時,無需顯式為 cls 參數傳參。
和 self 一樣,cls 參數的命名也不是規定的(可以随意命名),隻是 Python 程式員約定俗稱的習慣而已。
除此之外,和執行個體方法最大的不同在于,類方法需要使用
@classmethod
進行修飾,例如:
class Bird:
# classmethod修飾的方法是類方法
@classmethod
def fly (cls):
print('類方法fly: ', cls)
注意,如果沒有 @classmethod,則 Python 解釋器會将 fly() 方法認定為執行個體方法,而不是類方法。
類方法推薦使用類名直接調用,當然也可以使用執行個體對象來調用(不推薦),例如:
# 調用類方法,Bird類會自動綁定到第一個參數
Bird.fly() #①
b = Bird()
# 使用對象調用fly()類方法,其實依然還是使用類調用,
# 是以第一個參數依然被自動綁定到Bird類
b.fly() #②
運作結果為:
類方法fly: <class '__main__.Bird'>
類方法fly: <class '__main__.Bird'>
可以看到,不管程式是使用類還是對象調用類方法,Python 都會将類方法的第一個參數綁定到類本身。
Python類靜态方法
靜态方法,其實就是我們學過的函數,和函數唯一的差別是,靜态方法定義在類這個空間(類命名空間)中,而函數則定義在程式所在的空間(全局命名空間)中。
靜态方法沒有類似 self、cls 這樣的特殊參數,是以 Python 解釋器不會對它包含的參數做任何類或對象的綁定,也正是因為如此,此方法中無法調用任何類和對象的屬性和方法,靜态方法其實和類的關系不大。
靜态方法需要使用
@staticmethod
修飾,例如:
class Bird:
# staticmethod修飾的方法是靜态方法
@staticmethod
def info (p):
print('靜态方法info: ', p)
靜态方法的調用,既可以使用類名,也可以使用類對象,例如:
#類名直接調用靜态方法
Bird.info("類名")
#類對象調用靜态方法
b = Bird()
b.info("類對象")
運作結果為:
靜态方法info: 類名
靜态方法info: 類對象
在使用 Python 程式設計時,一般不需要使用類方法或靜态方法,程式完全可以使用函數來代替類方法或靜态方法。但是在特殊的場景(比如使用工廠模式)下,類方法或靜态方法也是不錯的選擇。至于靜态方法和類方法的具體應用場景,後續章節用到時再做詳細介紹。