小伙伴们,今天小编又要来给大家分享一下好久没有讲到的Python啦,今天还是讲Python里的魔法方法,还记得上次的算数运算吗,今天我们要了解的是描述符,在开始之前,我们首先来回顾一下之前的一个知识点,四边形求面积

class Rectangle: def __init__(self,width=0,height=0): self.width=width self.height=height def __setattr__(self,name,value): if name == "square": self.width=value self.height=value else: super().__setattr__(name ,value) def getArea(self): return self.width * self.height r1 =Rectangle(4,5) r1.getArea() # 20 r1.square=10 r1.width #10 r1.height #10 r1.getArea() #100

python摄氏度转为华氏度(Python魔法方法二之神奇的描述符)(1)

好了,先小小的热身了一吧,我们要开始我们的正题描述符——property原理。

描述符(descripto),用一句话来解释,描述符就是某种特殊的类的实例指派给另一个类的属性。那么什么是特殊类型的类呢?就是至少要在这个类中定义__get__()、__set__()、.__delete__()三个特殊方法中任意一个。

下面是描述符相关的魔法方法:

魔法方法含义__get__(self,instance,owner)用于访问属性,它返回属性的值__set__(self,instance,value)将在属性分配操作中调用,不返回任何内容__delete__(self,instance)控制删除操作,不返回任何内容

我们先来看一个描述符例子:

class MyDecriptor: def __get__(self,instance,owner): print("getting……",self,instance,owner) def __set__(self,instance,value): print("setting",self,instance,value) def __delete__(self, instance): print("deleting", self, instance) class Test: x=MyDecriptor() #MyDecriptor是X的描述符 test=Test() test.x # getting…… <MyDecriptor object at 0x02E85D10> <Test object at 0x02E85D50> <class 'Test'> Test # <class 'Test'> test #<Test object at 0x02E85CB0> test.x="ityx" # setting <MyDecriptor object at 0x02E85D10> <Test object at 0x02E85D50> ityx

python摄氏度转为华氏度(Python魔法方法二之神奇的描述符)(2)

由于MyDescriptor实现了__get__()、__set__()、__delete__()方法,并且将它的类实例指派给Test类的属性,所以MyDescriptor就是所谓描述符类。

然后第二段将Test类实例化,然后尝试对x属性进行各种操作,当访问x属性的时候,python会自动调用描述符的__get__()方法,self是描述符类自身的实例;instance是这个描述符的拥着者所在的类的实例,在这个里也就是Test类的实例化;owner是这个描述符的拥有者所在的类本身。

对x属性进行赋值操作的时候,python会自动调用__set__()方法,前两个参数跟__get__()方法是一样的,最后一个参数value是等号右边的值。

再来看另外一个例子:

class MyProperty: 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 )#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) c = C() c.x="ITYX" c.x # 'ITYX' c._x # 'ITYX' del c.x

python摄氏度转为华氏度(Python魔法方法二之神奇的描述符)(3)

只要弄清楚描述符,那么property的秘密就不再是秘密了!property事实上就是一个描述符类。

然后接下来,我们来玩一个好玩的实例,生活中也经常用到的,定义一个温度类实例然后定义两个描述符类用于描述摄氏度和花摄氏度两个属性。两个属性会自动进行转换,也就是我们可以对这两种温度选择任意一个比如对摄氏度进行赋值,它能打印对应的华氏度温度值。

class Celsius:#摄氏度 def __init__(self,value=26.0): self.value=float(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):#instance 是公有者Temperature的实例对象 return instance.cel*1.8 32 def __set__(self,instance,value): instance.cel=(float(value)-32)/1.8 class Temperature: cel=Celsius() fah=Fahrenheit() temp=Temperature() temp.cel # 26.0 temp.cel=30 temp.fah # 86.0 temp.fah=100.0 temp.cel # 37.77777777777778

python摄氏度转为华氏度(Python魔法方法二之神奇的描述符)(4)

,