Python中的類的方法

Python v3.7.0

靜態方法

靜態方法實際就是類中的一個普通函數。主要是用來存放邏輯性的代碼,邏輯上屬於類,但是和類本身沒有關係,也就是說在靜態方法中,不會涉及到類中的屬性和方法的操作。可以理解爲,靜態方法是個獨立的、單純的函數,它僅僅託管於某個類的名稱空間中,便於使用和維護。

通常情況下,靜態方法使用@staticmethod裝飾器(或使用staticmethod())來聲明。如下面的例子:

import time

class TimeTest():
    def __init__(self, hour, minute, second):
        self.hour = hour
        self.minute = minute
        self.second = second

    @staticmethod
    def show_time():
        return time.strftime('%H:%m:%s', time.localtime())
   
if __name__ == '__main__':
    # 下面兩種方式都可以正確調用
    print(TimeTest.show_time())
    print(TimeTest(1, 0, 0).show_time()) 

運行結果爲:

20:04:1555158168
20:04:1555158168

在Python 3中,如果一個類的方法沒有self參數,不再需要必須聲明爲靜態方法,但是這樣的話只能通過類去調用這個方法,如果通過實例對象調用這個方法就會引發異常。

class Animal(object):
    # @staticmethod
    def greet():
        pass
    
if __name__ == '__main__':
    # 以下調用方式會報錯 
    Animal().greet()

異常信息:

TypeError: greet() takes 0 positional arguments but 1 was given

這是因爲greet方法沒有聲明爲靜態方法,類實例在調用此方法時,會將self參數傳入到方法中,而方法本身不接受任何參數,從而引發異常。

類方法

定義類方法需要使用裝飾器@classmethod (或使用classmethod()),傳入的第一個參數必須爲必須是當前類對象,該參數名一般約定爲“cls”,通過它來傳遞類的屬性和方法cls(不能傳實例的屬性和方法)。

類方法可以通過類直接調用,也可以通過實例直接調用。但無論哪種調用方式,第一個參數一定是類本身。

class Persion(object):
    @classmethod
    def treasure(cls):
        print(__name__, type(cls), cls, sep='||')

if __name__ == '__main__':
    # 類對象和實例對象都可以調用
    Persion.treasure()
    Persion().treasure()

運行結果爲:

__main__||<class 'type'>||<class '__main__.Persion'>
__main__||<class 'type'>||<class '__main__.Persion'>

從運行結果可以看出,無論是通過類調用還是實例調用,類方法都能正常工作。且通過打印cls,可以看出cls傳入的都是類實例本身。

這裏需要注意,如果存在類的繼承,那類方法獲取的類是類樹上最底層的類。如下,Someone類的treasure繼承自Persion類,但是從最後的運行結果中可以看到,方法運行時傳入的類是Someone,而非其父類。

class Someone(Persion):
    pass

if __name__ == '__main__':
    Someone.treasure()
    Someone().treasure()

運行結果:

 <class '__main__.Someone'>
<class 'type'> <class '__main__.Someone'>

實例方法

實例方法第一個參數必須是實例對象本身,該參數名一般約定爲“self”,通過它來傳遞實例對象的屬性和方法(也可以傳類的屬性和方法)。

實例方法在調用的時候,self 是自動傳遞的,所以不需要我們再處理,但如果使用類對象直接調用實例方法,則需要顯式地將實例作爲參數傳入。

class Test(object):
    def __init__(self, name):
        self.name = name

    def get_gender(self, gender):
        return ('{} is a {}').format(self.name, gender)


if __name__ == '__main__':
    alex = Test('Alex')
    anna = Test('Anna')
    # 下面兩種方式都可以正確調用
    print(alex.get_gender('boy'))
    print(Test.get_gender(anna,'girl'))

運行結果爲:

Alex is a boy
Anna is a girl

【To be continue…】

參考文檔

  1. Python 實例方法、類方法、靜態方法的區別與作用薔薇Nina
  2. Python類方法、靜態方法與實例方法BlackMatrix
  3. python中的類屬性、實例屬性、類方法、實例方法蒲公英上的塵埃
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章