和類屬性可細分爲類屬性和實例屬性一樣,類中的方法也可以有更細緻的劃分,具體可分爲類方法、實例方法和靜態方法,本節將詳細介紹這 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 編程時,一般不需要使用類方法或靜態方法,程序完全可以使用函數來代替類方法或靜態方法。但是在特殊的場景(比如使用工廠模式)下,類方法或靜態方法也是不錯的選擇。至於靜態方法和類方法的具體應用場景,後續章節用到時再做詳細介紹。