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