日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python中的 @staticmethod@classmethod方法

發(fā)布時間:2025/4/16 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python中的 @staticmethod@classmethod方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python面向對象編程中,類中定義的方法可以是 @classmethod 裝飾的類方法,也可以是 @staticmethod 裝飾的靜態(tài)方法,用的最多的還是不帶裝飾器的實例方法,如果把這幾個方法放一塊,對初學者來說無疑是一頭霧水,那我們該如何正確地使用它們呢?

先來看一個簡單示例:

class A(object): def m1(self, n): print("self:", self) @classmethod def m2(cls, n): print("cls:", cls) @staticmethod def m3(n): pass a = A() a.m1(1) # self: <__main__.A object at 0x000001E596E41A90> A.m2(1) # cls: <class '__main__.A'> A.m3(1)

我在類中一共定義了3個方法,m1 是實例方法,第一個參數(shù)必須是 self(約定俗成的)。m2 是類方法,第一個參數(shù)必須是cls(同樣是約定俗成),m3 是靜態(tài)方法,參數(shù)根據(jù)業(yè)務需求定,可有可無。當程序運行時,大概發(fā)生了這么幾件事(結合下面的圖來看)。

  • 第一步:代碼從第一行開始執(zhí)行 class 命令,此時會創(chuàng)建一個類 A 對象(沒錯,類也是對象,一切皆對象嘛)同時初始化類里面的屬性和方法,記住,此刻實例對象還沒創(chuàng)建出來。
  • 第二、三步:接著執(zhí)行 a=A(),系統(tǒng)自動調用類的構造器,構造出實例對象 a
  • 第四步:接著調用 a.m1(1) ,m1 是實例方法,內部會自動把實例對象傳遞給 self 參數(shù)進行綁定,也就是說, self 和 a 指向的都是同一個實例對象。
  • 第五步:調用A.m2(1)時,python內部隱式地把類對象傳遞給 cls 參數(shù),cls 和 A 都指向類對象。

?


?

?

嚴格意義上來說,左邊的都是變量名,是對象的引用,右邊才是真正的對像,為了描述方便,我直接把 a 稱為對象,你應該明白我說對象其實是它所引用右邊的那個真正的對象。

再來看看每個方法各有什么特性

實例方法

print(A.m1) # A.m1在py2中顯示為<unbound method A.m1> <function A.m1 at 0x000002BF7FF9A488> print(a.m1) <bound method A.m1 of <__main__.A object at 0x000002BF7FFA2BE0>>

A.m1是一個還沒有綁定實例對象的方法,對于未綁定方法,調用 A.m1 時必須顯示地傳入一個實例對象進去,而 a.m1是已經綁定了實例的方法,python隱式地把對象傳遞給了self參數(shù),所以不再手動傳遞參數(shù),這是調用實例方法的過程。

A.m1(a, 1) # 等價 a.m1(1)

如果未綁定的方法 A.m1 不傳實例對象給 self 時,就會報參數(shù)缺失錯誤,在 py3 與 py2 中,兩者報的錯誤不一致,python2 要求第一個參數(shù)self是實例對象,而python3中可以是任意對象。

A.m1(1) TypeError: m1() missing 1 required positional argument: 'n'

類方法

print(A.m2) <bound method A.m2 of <class '__main__.A'>> print(a.m2) <bound method A.m2 of <class '__main__.A'>>

m2是類方法,不管是 A.m2 還是 a.m2,都是已經自動綁定了類對象A的方法,對于后者,因為python可以通過實例對象a找到它所屬的類是A,找到A之后自動綁定到 cls。

A.m2(1) # 等價 a.m2(1)

這使得我們可以在實例方法中通過使用 self.m2()這種方式來調用類方法和靜態(tài)方法。

def m1(self, n): print("self:", self) self.m2(n)

靜態(tài)方法

print(A.m3) <function A.m3 at 0x000002BF7FF9A840> print(a.m3) <function A.m3 at 0x000002BF7FF9A840>

m3是類里面的一個靜態(tài)方法,跟普通函數(shù)沒什么區(qū)別,與類和實例都沒有所謂的綁定關系,它只不過是碰巧存在類中的一個函數(shù)而已。不論是通過類還是實例都可以引用該方法。

A.m3(1) # 等價 a.m3(1) ``` 以上就是幾個方法的基本介紹現(xiàn)在把幾個基本的概念理清楚了那么現(xiàn)在來說說幾個方法之間的使用場景以及他們之間的優(yōu)缺點### 應用場景 靜態(tài)方法的使用場景如果在方法中不需要訪問任何實例方法和屬性純粹地通過傳入參數(shù)并返回數(shù)據(jù)的功能性方法那么它就適合用靜態(tài)方法來定義它節(jié)省了實例化對象的開銷成本往往這種方法放在類外面的模塊層作為一個函數(shù)存在也是沒問題的而放在類中僅為這個類服務例如下面是微信公眾號開發(fā)中驗證微信簽名的一個例子它沒有引用任何類或者實例相關的屬性和方法 from hashlib import sha1 import tornado.web class SignatureHandler(tornado.web.RequestHandler): def get(self): """ 根據(jù)簽名判斷請求是否來自微信 """ signature = self.get_query_argument("signature", None) echostr = self.get_query_argument("echostr", None) timestamp = self.get_query_argument("timestamp", None) nonce = self.get_query_argument("nonce", None) if self._check_sign(TOKEN, timestamp, nonce, signature): logger.info("微信簽名校驗成功") self.write(echostr) else: self.write("你不是微信發(fā)過來的請求") @staticmethod def _check_sign(token, timestamp, nonce, signature): sign = [token, timestamp, nonce] sign.sort() sign = "".join(sign) sign = sha1(sign).hexdigest() return sign == signature ?

類方法的使用場景有:

作為工廠方法創(chuàng)建實例對象,例如內置模塊 datetime.date 類中就有大量使用類方法作為工廠方法,以此來創(chuàng)建date對象。

class date:def __new__(cls, year, month=None, day=None): self = object.__new__(cls) self._year = year self._month = month self._day = day return self @classmethod def fromtimestamp(cls, t): y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t) return cls(y, m, d) @classmethod def today(cls): t = _time.time() return cls.fromtimestamp(t)

如果希望在方法裡面調用靜態(tài)類,那么把方法定義成類方法是合適的,因為要是定義成靜態(tài)方法,那么你就要顯示地引用類A,這對繼承來說可不是一件好事情。

class A:@staticmethoddef m1() pass @staticmethod def m2(): A.m1() # bad @classmethod def m3(cls): cls.m1() # good ?

?

轉載于:https://www.cnblogs.com/getniukou/p/11471208.html

總結

以上是生活随笔為你收集整理的Python中的 @staticmethod@classmethod方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。