9.描述符 裝飾器

描述符:

描述符本質(zhì)是一個(gè)新式類圾旨,在這個(gè)新式類中,至少出現(xiàn)了__get__()__set__()或者__delete__()方法中的一個(gè)廓鞠,也被稱為描述符協(xié)議帚稠。

  • __get__()obj.name調(diào)用一個(gè)屬性的時(shí)候觸發(fā)
  • __set__()obj.name = "bill"為一個(gè)屬性賦值的時(shí)候觸發(fā)
  • __delete__()del obj.name采用del刪除屬性的時(shí)候,觸發(fā)

描述符分為兩種:

  • 數(shù)據(jù)描述符 至少實(shí)現(xiàn)了__get__()__set__()
  • 非數(shù)據(jù)描述符 沒有實(shí)現(xiàn)__set__()

注意:對(duì)象本身調(diào)用不會(huì)觸發(fā)描述符協(xié)議床佳,當(dāng)該新式類為別的類的屬性滋早,通過別的類來調(diào)用該新式類時(shí)候才會(huì)觸發(fā)“

class Foo:
    def __set__(self, instance, value):
    # 可以通過__dict__屬性字典設(shè)置,在設(shè)置前可以增加判斷等操作
 
        print("hahaha")


class Tmp:
    #Foo()是數(shù)據(jù)描述符 代理了foo對(duì)象的屬性調(diào)用相關(guān)方法
    foo = Foo()

result = Tmp()
result.foo = "asdf"

函數(shù)裝飾器復(fù)習(xí)

前有函數(shù)裝飾器:

def foo(func):
    print("裝飾器")
    return func;

@foo   # 這一步就等于func1 = foo(func1)
def func1():
    print("func1")


func1()

類裝飾器使用

終極代碼:類裝飾器 + 描述符

class TypedC:
    def __init__(self, key, classType):
        self.key = key
        self.classType = classType

    def __get__(self, instance, owner):
        return instance.__dict__[self.key]

    def __set__(self, instance, value):
        if not isinstance(value, self.classType):
            raise TypeError("傳入的數(shù)據(jù)類型有問題")
        instance.__dict__[self.key] = value


def out_deco(**kwargs):
    def in_deco(obj):
        for key, value in kwargs.items():
            setattr(obj, key, TypedC(key,value))
        return obj
    return deco


@out_deco(name=str, age=int)
class New:

    def __init__(self, name, age):
        self.name = name
        self.age = age



print(New("alex",100).__dict__)

解釋:

@out_deco(name=str, age=int)
先忽略@砌们,即執(zhí)行右半邊方法: out_deco(name=str, age=int)  -> out_deco({字典}) 
得到:
@in_deco(New)   相當(dāng)于   New = in_deco(New)

然后執(zhí)行in_deco(New)內(nèi)部循環(huán):
setattr(obj, key, TypedC(key,value))  相當(dāng)于  New.key = TypedC("name", str)




自定義裝飾器

使用類裝飾器 模擬系統(tǒng)@property的實(shí)現(xiàn)

class Deco_class:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):
        return self.func(instance)


class Foo:
    def __init__(self):
        pass

    @Deco_class
    def showAnim(self):
        print("show anim 運(yùn)行")

obj = Foo()
obj.showAnim

改進(jìn)版:儲(chǔ)存函數(shù)執(zhí)行結(jié)果杆麸,下次不用重復(fù)計(jì)算執(zhí)行

class Deco_class:
    def __init__(self, func):
        self.func = func

    # 因?yàn)闆]有重寫__set__方法,所以是非數(shù)據(jù)描述符浪感,優(yōu)先級(jí)比實(shí)例屬性低
    def __get__(self, instance, owner):

        res = self.func(instance)
        # 儲(chǔ)存結(jié)果到實(shí)例對(duì)象中后 下次調(diào)用 由于優(yōu)先級(jí)的問題  會(huì)優(yōu)先從實(shí)例對(duì)象中查找showAnim方法昔头,而不是調(diào)用非數(shù)據(jù)描述符
        setattr(instance, self.func.__name__, res)
        return res


class Foo:
    def __init__(self):
        pass

    @Deco_class
    def showAnim(self):
        print("show anim 運(yùn)行")

obj = Foo()
obj.showAnim


補(bǔ)充:

使用@property裝飾器修飾的方法,不可以賦值篮撑,需要:

class Foo:

    @property
    def showAnim(self):
        print("show anim 運(yùn)行")

    @showAnim.setter
    def showAnim(self, name):
        print("show anim 運(yùn)行", name)

obj = Foo()
obj.showAnim

obj.showAnim = "bill"

另一種寫法:

class Foo:

    def get_a(self):
        print("get method")

    def set_a(self, val):
        print("set method")

    def del_a(self):
        print("del method")

    aaa = property(get_a, set_a, del_a)

obj = Foo()
obj.aaa = "bill"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末减细,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子赢笨,更是在濱河造成了極大的恐慌未蝌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茧妒,死亡現(xiàn)場(chǎng)離奇詭異萧吠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)桐筏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門纸型,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人梅忌,你說我怎么就攤上這事狰腌。” “怎么了牧氮?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵琼腔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我踱葛,道長(zhǎng)丹莲,這世上最難降的妖魔是什么光坝? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮甥材,結(jié)果婚禮上盯另,老公的妹妹穿的比我還像新娘。我一直安慰自己洲赵,他們只是感情好鸳惯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著板鬓,像睡著了一般悲敷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俭令,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音部宿,去河邊找鬼抄腔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛理张,可吹牛的內(nèi)容都是我干的赫蛇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼雾叭,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼悟耘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起织狐,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤暂幼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后移迫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旺嬉,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年厨埋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了邪媳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡荡陷,死狀恐怖雨效,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情废赞,我是刑警寧澤徽龟,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蛹头,受9級(jí)特大地震影響顿肺,放射性物質(zhì)發(fā)生泄漏戏溺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一屠尊、第九天 我趴在偏房一處隱蔽的房頂上張望旷祸。 院中可真熱鬧,春花似錦讼昆、人聲如沸托享。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闰围。三九已至,卻和暖如春既峡,著一層夾襖步出監(jiān)牢的瞬間羡榴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國打工运敢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留校仑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓传惠,卻偏偏與公主長(zhǎng)得像迄沫,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子卦方,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

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

  • 不知道什么叫打元卯羊瘩?不知道就對(duì)了。不是小朋友那個(gè)地方長(zhǎng)大的盼砍,知道什么是打元卯才怪尘吗。 讓小朋友來告訴...
    荊郢豪客閱讀 177評(píng)論 0 0
  • 本身自己就有記日記的習(xí)慣,所以先把私人日記曝光一下3耐ⅰ(因?yàn)橥6际亲约弘S便寫寫摇予,字跡過于灑脫,有必要為朋友們翻譯一...
    麗美666閱讀 282評(píng)論 5 1
  • 不要來找我吗跋,不要來想我侧戴,也不要……愛上我。 九年八個(gè)月前跌宛,你給我發(fā)了一條信息酗宋,讓我去五月二十日那個(gè)雨天我們一起避雨...
    青亦墨傾閱讀 446評(píng)論 0 2