1. 程式人生 > 實用技巧 >Python例項方法、類方法和靜態方法

Python例項方法、類方法和靜態方法

Python類的組成主要包含兩個部分,類的屬性和類的方法。類的屬性是對資料的封裝,這些資料是用來描述類所抽象的事物的特徵;類的方法是用來表示物件的特定行為。Python的類的方法又可以進一步細分分為三種不同型別,即例項方法、類方法和靜態方法。

這裡就是對類的這三種方法進行詳細討論,包括它們是如何實現、如何被呼叫以及各自的特點。

例項方法

例項方法是你在Python中將會在大多數情況下使用到的最基本、最簡單的方法,該方法必須接受一個引數,一般情況下我們將這個引數約定寫成self,self引數傳入的是類的例項化物件。

例項方法的使用:

定義了一個student類,student類中實現了一個名為get_info例項方法,在get_info例項方法中打印出物件相關資訊。

class student(object):
    def __init__(self, _name, _age):
        self.name = _name
        self.age  = _age
        
    def get_info(self):
        print('%s is %d years old !' %(self.name, self.age))

if __name__ == '__main__':
  s = student('LiMing', 12)
  s.get_info()

s是使用student類例項化的物件,類的例項方法通過 s.get_info() 方式被呼叫。在呼叫例項方法時,s例項物件會被自動的作為引數傳給get_info中的第一個self引數中,self也就代表s物件。

可以看出,通過self引數,例項方法可以自由地訪問同一物件上的屬性和其他方法。當涉及到修改物件的狀態時,例項方法就非常給力。

類方法

類方法在Python中使用的比較少,類方法不接受self引數,而是接受一個cls引數,cls引數呼叫時指向的是類而不是例項物件。通常情況下,類方法使用@classmethod裝飾器來修飾。與例項方法不同的是,類方法可以通過類直接呼叫,也可以通過例項物件直接呼叫。但無論哪種呼叫方式,最左側傳入的引數一定是類本身。

(注意cls引數和例項方法self引數一樣也是約定寫成的,可以使用其它名字代替)

類方法的使用:

使用類方法增加前面定義的student類的功能,讓每個student類的物件可以得到當前例項化student物件的個數。

class student(object):
    total_num = 0
    
    def __init__(self, _name, _age):
        self.name = _name
        self.age  = _age
        
    def __new__(cls, *args, **kwargs):
        cls.set_num()
        return object.__new__(cls)
        
    @classmethod
    def set_num(cls):
        cls.total_num += 1
        
    @classmethod
    def get_num(cls):
        return cls.total_num
        
    def get_info(self):
        print('%s is %d years old !' %(self.name, self.age))

if __name__ == "__main__":
    a = student('a', 10)
print(a.get_num()) b = student('b', 10) print(b.get_num())

新的student類中引入的類屬性total_num,重寫了__new__方法,使得在每次建立一個例項物件時能呼叫類方法set_num讓類屬性total_num加一,total_num代表當前例項化student個數。set_num和get_num都是類方法,它只能訪問到類屬性。

類屬性和例項屬性有所不同,不管建立了多少類物件,他們的類屬性只有1個,也就是說類屬性屬於類而不屬於物件。

類方法實現工廠模式

class student(object):
    
    def __init__(self, _name, _age):
        self.name = _name
        self.age  = _age
        
    def get_info(self):
        print('%s is %d years old !' %(self.name, self.age))
        
    @classmethod
    def factory(cls):
        return cls('init', 10)
        
if __name__ == "__main__":
    a = student.factory()
    b = student.factory()
    print(a)
    print(b)

靜態方法

靜態方法即不接受self引數,也不接受cls引數,但它可以接受其他任意數量的引數。與類方法一樣,靜態方法也使用一個裝飾器修飾,修飾符為@staticmethod。

由於靜態方法不接受self引數和cls引數,靜態方法不能修改物件狀態和類狀態。因此,靜態方法主要是用來存放邏輯性的程式碼,邏輯上屬於類,但是和類本身沒有關係。可以理解為,靜態方法是個獨立的、單純的函式,它僅僅託管於某個類的名稱空間中,便於使用和維護。

靜態方法的使用:

class student(object):
    
    def __init__(self, _name, _age):
        self.name = _name
        self.age  = _age
        
    def get_info(self):
        print('%s is %d years old !' %(self.name, self.age))
        
    @staticmethod
    def do_something(string):
        print(string)
        
if __name__ == "__main__":
    a = student('a', 10)
    a.do_something('staticmethod')

靜態方法的呼叫方式和類例項方法的呼叫方式一樣,只是在呼叫時Python直譯器不會將例項物件強制繫結在靜態方法的第一個引數上。a.do_something('staticmethod')即靜態方法的呼叫。

小結

  • 例項方法需要例項物件呼叫,通過self引數訪問到該例項。例項方法可以用來修改例項化物件的狀態資訊。
  • 類方法不能訪問到類的例項物件狀態,但它可以訪問類的屬性。類方法可以使用類呼叫,也可以使用例項直接呼叫,但傳入的類方法左側的引數是類本身。
  • 靜態方法無權訪問到self和cls,可以看成是一個獨立的、單純的函式,但它屬於類的名稱空間中。