Python基础入门学习笔记 046 魔法方法:描述符(Property的原理)

发布时间 2023-08-23 11:04:21作者: 一杯清酒邀明月

描述符

•描述符就是将某种特殊类型的类的实例指派给另一个类的属性。

•__get__(self, instance, owner)

–用于访问属性,它返回属性的值

•__set__(self, instance, value)

–将在属性分配操作中调用,不返回任何内容

•__delete__(self, instance)

–控制删除操作,不返回任何内容

实例:

 1 >>> class MyDecriptor:
 2     def __get__(self,instance,owner):
 3         print("getting...",self,instance,owner)
 4     def __set__(self,instance,value):
 5         print("setting...",self,instance,value)
 6     def __delete__(self,instance):
 7         print("deleting...",self,instance)
 8 
 9  
10 
11 >>> class Test:
12     x = MyDecriptor()   #取Mydecriptor类的实例指派给Test类的属性x
13 
14 >>> test = Test()
15 >>> test.x
16 getting... <__main__.MyDecriptor object at 0x00000000033467F0> <__main__.Test object at 0x000000000335EF98> <class '__main__.Test'>
17 >>> test
18 <__main__.Test object at 0x000000000335EF98>
19 >>> test.x = "X-man"
20 setting... <__main__.MyDecriptor object at 0x00000000033467F0> <__main__.Test object at 0x000000000335EF98> X-man
21 >>> del test.x
22 deleting... <__main__.MyDecriptor object at 0x00000000033467F0> <__main__.Test object at 0x000000000335EF98>

实例2:

 1 >>> class MyProperty:
 2     def __init__(self,fget = None,fset = None,fdel = None):
 3         self.fget = fget
 4         self.fset = fset
 5         self.fdel = fdel
 6     def __get__(self,instance,owner):
 7         return self.fget(instance)
 8     def __set__(self,instance,value):
 9         self.fset(instance,value)
10     def __delete__(self,instance):
11         self.fdel(instance)
12 
13         
14 >>> class C:
15     def __init__(self):
16         self._x = None
17     def getX(self):
18         return self._x
19     def setX(self,value):
20         self._x = value
21     def delX(self):
22         del self._x
23     x = MyProperty(getX,setX,delX)
24 
25     
26 >>> c = C()
27 >>> c.x = "HELLOW"
28 >>> c.x
29 'HELLOW'
30 >>> c._x
31 'HELLOW'
32 >>> del c.x
33 >>> c._x
34 Traceback (most recent call last):
35   File "<pyshell#70>", line 1, in <module>
36     c._x
37 AttributeError: 'C' object has no attribute '_x'

练习要求

•先定义一个温度类,然后定义两个描述符类用于描述摄氏度和华氏度两个属性。

•要求两个属性会自动进行转换,也就是说你可以给摄氏度这个属性赋值,然后打印的华氏度属性是自动转换后的结果。

实例3:

 1 ss Celsius:  #摄氏度描述符类
 2     def __init__(self,value = 26.0):#self为描述符类自身(此为摄氏度描述符类)的实例(此为cel)
 3         self.value = float(value)
 4     def __get__(self,instance,owner):#instance是这个描述符的拥有者所在的类的实例(此为temp)
 5         return self.value
 6     def __set__(self,instance,value):#owner是这个描述符的拥有者所在的类本身(此为温度类)
 7         self.value = float(value)
 8 
 9 class Fahrenheit:   #华氏度描述符类
10     def __get__(self,instance,owner):
11         return instance.cel * 1.8 +32  #摄氏度转华氏度
12     def __set__(self,instance,value):
13         instance.cel = ((float)(value)- 32)/ 1.8   #华氏度转摄氏度
14         
15 class Temperature:   #温度类
16     cel = Celsius()   #设置摄氏度属性(描述符类的实例指派给了温度类的属性)
17     fah = Fahrenheit()#设置华氏度属性
18 
19 >>> temp = Temperature()
20 >>> temp.cel
21 26.0
22 >>> temp.fah
23 78.80000000000001
24 >>> temp.fah = 78.8
25 >>> temp.cel
26 25.999999999999996