Python魔法方法之描述符

大家都知道Python有很多有趣的魔法方法,今天我們要說的是描述符這一魔法方法:

先來看一個Demo吧:

class A():
    def __init__(self):
        self.a = 10
    def getA(self):
        return self.a
    def setA(self, a):
        self.a = a
    def delA(self):
        del self.a
    '''將x與a聯繫起來 三個參數分別對應獲得函數 賦值函數 刪除函數'''
    x = property(getA,setA,delA)
if __name__ == '__main__':
    q = A()
    print(q.x)#等價於print(q.a)
    q.x = 11#等價於調用set函數賦值 q.setA(11)
    print(q.a)

在上面的模塊中,我們完全可以通過操作x來替代對a的操作,這就是描述符的作用。

下面我們來看這個麪塑負的實現原理:可以看到我們自定義的描述符添加了幾個魔法方法,這就是描述符的原理所在了:

這我們所寫的魔法方法中 instance我們就可以理解爲是調用我們自定義描述符的C類的一個實例 self就是描述符本身的實例

這樣去想應該就很容易理解它的原理 這幾個魔法方法都是會在實例被賦值或被訪問、刪除是自動調用的 要不然也稱不上是魔法方法,只一點要清楚

class MyProperty():
    '''在這裏instance就是C類創建的一個實例 self就是x'''
    def __init__(self, fget=None, fset=None, fdel=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
    def __get__(self, instance, owner):
        return self.fget(instance)

    def __set__(self, instance, value):
        self.fset(instance, value)

    def __delete__(self, instance):
        self.fdel(instance)
class C():
    def __init__(self):
        self._x = None
    def getX(self):
        return self._x
    def setX(self,value):
        self._x = value
    def delX(self):
        del self._x
    x = MyProperty(getX, setX, delX)

最後,我們再來實現一個溫度轉換的功能,當然是利用描述符來實現:

稍微的來說明一下吧:一開始我們進行了賦值即 t.fan = 100 那麼就會進入到Fahrenheit的__set__方法裏 然後就又會轉到

Celsius的__set__方法裏 下一步就是print(t.cel)就會轉到Celsius的__get__方法直接打印出了轉換後的溫度,我認爲基本流層就是這樣,如有錯誤還請評論區斧正


class Celsius():
    def __init__(self, value = 26.0):
        self.value = value
    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        self.value = float(value)

class Fahrenheit():
    def __get__(self, instance, owner):
        return instance.cel * 1.8 + 32
    def __set__(self, instance, value):
        instance.cel = (float(value) - 32) / 1.8

class Temperature():
    '''相當於兩個property'''
    cel = Celsius()
    fah = Fahrenheit()
if __name__ == '__main__':
    t = Temperature()
    t.fah = 100#賦值操作
    print(t.cel)
    t.cel = 38#賦值操作
    print(t.fah)
    

輸出:

37.77777777777778
100.4

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章