大家都知道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