Python類裝飾器@classmethod, @staticmethod, @property, since 2022-02-15

(2022.02.15 Tues)
Python類自帶了三個(gè)裝飾器嗓节。被@classmethod裝飾的方法是類方法,被@staticmethod裝飾的方法是靜態(tài)方法帕膜,沒有裝飾器的方法是實(shí)例方法枣氧。

@classmethod 類方法

該裝飾器用于修飾類的方法中的類方法,該方法不因?qū)嵗淖儭?br> 調(diào)用方式:

  • class_name.method_name:在調(diào)用經(jīng)@classmethod修飾的類方法時(shí)不需要實(shí)例化類垮刹。
  • instance_name.method_name:也可在實(shí)例化之后通過實(shí)例化的類名加方法名來調(diào)用达吞。

類方法定義不需要指定self作為輸入?yún)?shù),但第一個(gè)傳遞的參數(shù)必須是自身類的cls荒典,可用來調(diào)用類的方法酪劫,實(shí)例化對(duì)象等吞鸭。可以返回一個(gè)類覆糟。定義格式如

class A:
    @classmethod
    def func(cls, args1, args2, ...):
        pass

該裝飾器的優(yōu)勢在于刻剥,當(dāng)重構(gòu)類的時(shí)候不需要修改構(gòu)造函數(shù),只需要添加新的方法滩字,并用@classmethod裝飾即可透敌。

# 初始類
class Data_test(object):
    day=0
    month=0
    year=0

    def __init__(self,year=0,month=0,day=0):
        self.day=day
        self.month=month
        self.year=year

    def out_date(self):
        print("year : ", self.year, ", month: ", self.month, ", day: ", self.day)

# 新增
class Str2IntParam(Data_test):
    @classmethod
    def get_date(cls, string_date):
        #這里第一個(gè)參數(shù)是cls, 表示調(diào)用當(dāng)前的類名
        year, month, day = map(int, string_date.split('-'))
        date1 = cls(year, month, day)
        #返回的是一個(gè)初始化后的類
        return date1
$ r = Str2IntParam.get_date("2016-8-1")
$ r.out_date()
year: 2016, month: 8, day: 1

@classmethod修飾的類方法可修改類的狀態(tài)踢械,并應(yīng)用于類的所有對(duì)象,比如可通過類方法修改類變量并應(yīng)用于類的所有對(duì)象魄藕。It would modify the class state that would apply across all the instances of the class. For example, it can modify a class variable that would be applicable to all the instances.
(2022.02.21 Mon)
在下面這個(gè)例子中内列,類方法用于在每次類實(shí)例化時(shí)更新類變量cntr。注意查看每次實(shí)例化之前和之后類變量的值背率。

class DemoClass:
    cntr = 0
    def __init__(self, name):
        self.name = name
        self.cntr = self.cntr_number()

    @classmethod
    def cntr_number(cls):
        cls.cntr += 1
        return cls.cntr
>>> DemoClass.cntr
0
>>> a = DemoClass(1)
>>> DemoClass.cntr
1
>>> b = DemoClass(2)
>>> DemoClass.cntr
2
>>> a.cntr
1

上面的演示說明類方法的使用使得類具有記憶力话瞧。這個(gè)特性可應(yīng)用于深度學(xué)習(xí)的模型訓(xùn)練。

Python不支持類似于C++/Java中的方法重載(method overloading)寝姿,于是使用@classmethod修飾的類方法創(chuàng)建工廠方法(factory method)交排。在不同的案例中,工廠方式可以返回類對(duì)象饵筑,就像一個(gè)構(gòu)造函數(shù)(constructor)埃篓。

@staticmethod 靜態(tài)方法

(2022.02.16 Wed)
該指令修飾靜態(tài)方法。靜態(tài)方法的輸入?yún)?shù)沒有要求根资,不需要傳入類方法的cls作為輸入?yún)?shù)架专,也不需要傳入實(shí)例方法中的self作為輸入?yún)?shù),傳入?yún)?shù)可以任意指定玄帕。
調(diào)用方式:

  • class_name.method_name
  • instance_name.method_name部脚,在實(shí)例化后。

靜態(tài)方法不改變類的行為和狀態(tài)裤纹,靜態(tài)方法不需要類本身作為一個(gè)輸入?yún)?shù)委刘,靜態(tài)方法甚至可以放在類之外單獨(dú)定義。在Python提出類的設(shè)計(jì)之前鹰椒,通常在全局namespace中創(chuàng)建函數(shù)锡移。類中加入靜態(tài)方法很多時(shí)候是方便類的使用(?)使用靜態(tài)方法甚至有時(shí)是糟糕設(shè)計(jì)的標(biāo)志。

import time
class ClassA:
   def __init__(self):
       pass
    @staticmethod
    def show_time():
        print(time.perf_time())

@property property方法

(2022.02.21 Mon)
@property裝飾器將方法轉(zhuǎn)換為同名的屬性吹零,即調(diào)用該方法時(shí)不加擴(kuò)號(hào)罩抗,將方法當(dāng)成一個(gè)只讀屬性來調(diào)用。配合所定義的屬性灿椅,可以防止對(duì)屬性的修改套蒂。

class demoClass:
    @property
    def attr(self):
        return '99g1'
    def no_property(self):
        return '99g1aswell'

實(shí)例化并調(diào)用的結(jié)果如下

>>> a.attr
'99g1'
>>> a.attr()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>> a.no_property()
'99g1aswell'
>>> a.no_property
<bound method demoClass.no_property of <__main__.demoClass object at 0x10f0de370>>

Python中無法設(shè)置私有屬性钞支,卻可通過@property來設(shè)置私有屬性,隱藏屬性名操刀,使得用戶無法修改烁挟。

class dataSet:
    def __init__(self):
        self._var1 = 1
        self._var2 = 2
        
    @property
    def var1(self):
        return self._var1
    @property
    def var2(self):
        return self._var2

調(diào)用如下

>>> c = dataSet()
>>> c.var1
1
>>> c._var1
1
>>> c.var2
2
>>> c._var2
2

(2022.02.22 Tues)
下面通過一個(gè)例子演示類的繼承過程中,子類對(duì)父類中不同方法的繼承方式骨坑。

class allMethod:
    x = 1
    y = 2 
    @classmethod
    def classm(cls):
        return cls.x + cls.y
    @staticmethod
    def staticm():
        return allMethod.x + allMethod.y
    @property
    def propertym(self):
        return self.x

class testClass(allMethod):
    x = 7
    y = 5

實(shí)例化子類

>>> d = testClass()
>>> d.classm()
12
>>> d.staticm()
3
>>> d.propertym
7

對(duì)子類實(shí)例化之后撼嗓,我們看到

  • @classmethod類方法:實(shí)例中的類方法調(diào)用的是子類的方法和子類的屬性。因類方法傳遞的參數(shù)是cls欢唾,即子類本身且警。
  • @staticmethod靜態(tài)方法:實(shí)例中的靜態(tài)方法調(diào)用的父類的方法和父類的屬性。因靜態(tài)方法傳遞的參數(shù)是原始類名(父類名)礁遣。
  • @propertyproperty方法:實(shí)例中的property方法調(diào)用的子類的屬性斑芜。因property方法傳遞的參數(shù)是self,即子類對(duì)象祟霍。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末杏头,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子沸呐,更是在濱河造成了極大的恐慌醇王,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崭添,死亡現(xiàn)場離奇詭異寓娩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)滥朱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門根暑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人徙邻,你說我怎么就攤上這事排嫌。” “怎么了缰犁?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵淳地,是天一觀的道長。 經(jīng)常有香客問我帅容,道長颇象,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任并徘,我火速辦了婚禮遣钳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘麦乞。我一直安慰自己蕴茴,他們只是感情好劝评,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著倦淀,像睡著了一般蒋畜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上撞叽,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天姻成,我揣著相機(jī)與錄音,去河邊找鬼愿棋。 笑死科展,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的糠雨。 我是一名探鬼主播辛润,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼见秤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起真椿,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤鹃答,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后突硝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體测摔,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年解恰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锋八。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡护盈,死狀恐怖挟纱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腐宋,我是刑警寧澤紊服,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站胸竞,受9級(jí)特大地震影響欺嗤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卫枝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一煎饼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧校赤,春花似錦吆玖、人聲如沸筒溃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铡羡。三九已至,卻和暖如春意鲸,著一層夾襖步出監(jiān)牢的瞬間烦周,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工怎顾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留读慎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓槐雾,卻偏偏與公主長得像夭委,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子募强,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容