小夥伴們,今天小編又要來給大家分享一下好久沒有講到的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
好了,先小小的熱身了一吧,我們要開始我們的正題描述符——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
由于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
隻要弄清楚描述符,那麼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
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!