python之屬性描述符

做爲一個小白,天天都在不斷地看東西,學知識,今天給你們介紹一個好東西——屬性描述符
什麼是屬性描述符呢?
其實在一個類中實現set__、__get__、__delete中任意一個魔法函數就是一個屬性描述符。
接下來咱們定義一個屬性描述符:函數

class IntegerField:
    def __get__(self, instance, owner):
        pass

    def __set__(self, instance, value):
        pass

    def __delete__(self, instance):
        pass


class User:
    high= IntField()

__get__:當咱們用類或者實例來調用該屬性時,會返回__get__函數的結果。
__set__:當咱們用實例來設置屬性值時,Python會調用該函數。對類沒有限制做用。
__delete__:當咱們用實例試圖刪除該屬性時,Python會調用該函數。對類沒有限制做用。
__set__中參數:self->描述符實例, instance->託管實例, value->設置值
__get__中參數:self->描述符實例, instance->託管實例, owner->託管類的引用
到底這個東西怎麼用呢?接下來爲你們修改上面的代碼code

class IntegerField:
    def __get__(self, instance, owner):
        return self.value
        
    def __set__(self, instance, value):
        if not isinstance(value,numbers.Integral):
            raise ValueError("請輸入一個整數")
        self.value=value
        
    def __delete__(self, instance):
        pass


class User:
    high=IntegerField()
    
#驗證代碼
if __name__ == '__main__':
    user=User()
    user.high='175'    #報錯,ValueError:請輸入一個整數
    User.high=175    #正確執行,不報錯

這樣咱們就可以運用屬性描述符來給屬性附上必定的邏輯了。
其實在屬性描述符下還分爲
一、數據描述符:實現了__set__、__get__get

if __name__ == '__main__':
    user=User()
    user.high=175
    print(user.__dict__)    #high是不放入__dict__中的,優先查找數據描述符中的值
    user.__dict__["high"]="abc"    #這樣賦值時能夠的,而且能夠放入__dict__中
    print(user.high)    #會報錯,由於在調用__get__方法時並無value屬性

二、非數據:實現__get__不實現__set__it

class NonField:
    def __init__(self, high=170):
        self.value = high

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


class User:
    high = NonField()


if __name__ == '__main__':
    user = User()
    user.high = '175'    #會放入user.__dict__中
    print(user.__dict__)
相關文章
相關標籤/搜索