Python中的 staticmethod 和 classmethod

眾所周知,類是創(chuàng)建實(shí)例的模板,而實(shí)例是一個(gè)個(gè)具體的對(duì)象,各個(gè)實(shí)例擁有的數(shù)據(jù)相互獨(dú)立、互不影響。

在類中定義的函數(shù)稱為方法,主要有三種:實(shí)例方法、類方法、靜態(tài)方法

class A:

    def instance_method(self, n):
        print('self', self)

    @classmethod
    def class_method(cls, n):
        print('cls', cls)

    @staticmethod
    def static_method():
        print('this is a static method')

上面類 A 定義的三個(gè)方法分別是實(shí)例方法、類方法、靜態(tài)方法,下面我們來(lái)詳細(xì)分析

實(shí)例方法

不帶裝飾器的實(shí)例方法在類定義中是最常見的:

定義中,傳入的第一個(gè)參數(shù)必須是 self,表示實(shí)例本身,在其中可使用 self.attr 獲取實(shí)例的屬性。

a = A()
a.instance_method(2)
print(A.bar)
print(a.bar)

下面是程序運(yùn)行結(jié)果:

self <__main__.A object at 0x0000028554C87E48>
grg
grg

當(dāng)我們創(chuàng)建了實(shí)例 a 之后,調(diào)用 a.instance_method(2) 時(shí),實(shí)例 a 會(huì)被自動(dòng)傳入函數(shù)作為 self 參數(shù)。

如果我們調(diào)用 A.instance_method(2) 時(shí)會(huì)發(fā)生什么呢?即,類能不能調(diào)用實(shí)例方法?

Traceback (most recent call last):
  File "I:\Program Code\Python\test2.py", line 32, in <module>
    A.instance_method(2)
TypeError: instance_method() missing 1 required positional argument: 'n'

可以看到,數(shù)字 2 被傳入 self 參數(shù)了,所以才會(huì)提示缺少一個(gè)位置參數(shù) n,所以,實(shí)例方法不能由類調(diào)用。

順便提一句,屬性也分實(shí)例屬性和類屬性,上例直接定義的是類屬性,類和類實(shí)例都可以訪問(wèn)。類中定義的方法也可以無(wú)限制訪問(wèn)這個(gè)類屬性。

通過(guò) __init__(self,attr) 定義的是實(shí)例屬性,只有實(shí)例能訪問(wèn),類不能訪問(wèn)。類中定義的屬性只有傳進(jìn)了 self 參數(shù)的方法(通常就是實(shí)例方法)可訪問(wèn)。

classmethod

無(wú)需實(shí)例化,但與實(shí)例方法第一個(gè)參數(shù)必須是 self 類似,類方法第一個(gè)參數(shù)表示類自身的 cls 參數(shù),可以來(lái)調(diào)用類的屬性、類的方法、類的實(shí)例化對(duì)象等

a.class_method(2)
A.class_method(2)

觀察上面代碼的運(yùn)行結(jié)果:

cls <class '__main__.A'>
cls <class '__main__.A'>

可知,類方法既可以由類調(diào)用,也可以由實(shí)例調(diào)用。

再來(lái)看一個(gè)例子:

class Book(object):
    def __init__(self, title):
        self.title = title

    @classmethod
    def create(cls, title):
        book = cls(title)
        return book


book1 = Book('A song of Ice and Fire')
book2 = Book.create('The Marvel')
print(book1.title)
print(book2.title)

運(yùn)行結(jié)果如下:

A song of Ice and Fire
The Marvel

上面,類方法創(chuàng)建了一個(gè)類實(shí)例。

staticmethod

無(wú)需 self 參數(shù),無(wú)需 cls 參數(shù),直接聲明一個(gè)靜態(tài)方法,可無(wú)需實(shí)例化,直接由類調(diào)用,也可實(shí)例化后調(diào)用。

帶 staticmethod 裝飾器定義的就是靜態(tài)方法,與普通函數(shù)沒(méi)有區(qū)別,可以不加參數(shù),可以加任意參數(shù),不必傳入 self ,既可以由實(shí)例調(diào)用,也可以由類調(diào)用。

A.static_method()
a.static_method()

運(yùn)行結(jié)果如下:

this is a static method
this is a static method

總結(jié)

實(shí)例方法只能由實(shí)例調(diào)用,類方法和靜態(tài)方法可以由實(shí)例或類調(diào)用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡(jiǎn)書還為我保存起的...
    Jenaral閱讀 3,115評(píng)論 2 9
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 12,306評(píng)論 6 13
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,621評(píng)論 1 32
  • 今天是很不尋常的一天,今天也是感受另外一種生命的一天。放下了,完美放下了,放下了,別人對(duì)自己的評(píng)判,以及別人對(duì)自己...
    陳琦不黑閱讀 198評(píng)論 0 2
  • 嗨,靜言,今天是2017年的第一天。2016的你過(guò)得怎樣? happy for everyday,just a l...
    jamieT2311閱讀 342評(píng)論 0 2

友情鏈接更多精彩內(nèi)容