1、什么是描述符?
python描述符是一个“绑定行为”的对象属性,在描述符协议中,它可以通过方法重写属性的访问。这些方法有 __get__(), __set__(), 和__delete__()。如果这些方法中的任何一个被定义在一个对象中,这个对象就是一个描述符。
所以,某个类,只要是内部定义了方法 __get__, __set__, __delete__ 中的一个或多个,就可以称为描述符
描述符就是将某种特殊类型的类的实例指派给另一个类的属性
__get__(self,instance,owner)
用于访问属性,它返回属性的值
__set__(self,instance,value)
将在属性分配操作中调用,不返回任何内容
__delete__(self,instance)
>>> c.x = 'X-man'
>>> c.x
'X-man'
>>> c._x
'X-man'
>>> del c.x
>>> c.x
Traceback (most recent call last):
File "<pyshell#100>", line 1, in <module>
c.x
File "<pyshell#92>", line 8, in __get__
return self.fget(instance)
File "<pyshell#94>", line 6, in getx
return self._x
AttributeError: 'C' object has no attribute '_x'
>>>
>>> temp.cel
25.0
>>> temp.fah
482.0
>>> temp.cel = 38
>>> temp.fah
716.0
>>>
python描述符是一个“绑定行为”的对象属性,在描述符协议中,它可以通过方法重写属性的访问。这些方法有 __get__(), __set__(), 和__delete__()。如果这些方法中的任何一个被定义在一个对象中,这个对象就是一个描述符。
所以,某个类,只要是内部定义了方法 __get__, __set__, __delete__ 中的一个或多个,就可以称为描述符
描述符就是将某种特殊类型的类的实例指派给另一个类的属性
__get__(self,instance,owner)
用于访问属性,它返回属性的值
__set__(self,instance,value)
将在属性分配操作中调用,不返回任何内容
__delete__(self,instance)
控制删除操作,不返回任何内容
class MyDecriptor:
def __get__(self,instance,owner):
print('get',self,instance,owner)
def __set__(self,instance,value):
print('set',self,instance,value)
def __delete__(self,instance):
print('delete',self,instance)
class Test:
x = MyDecriptor() #MyDecriptor为实现了特殊类型的类,MyDecriptor()实例指派给Test类的属性x,所以MyDecriptor就是x的描述符
test = Test()
下面是IDLE环境
>>> test
<__main__.Test object at 0x000001C8A48EDEF0>
>>> test.x
get <__main__.MyDecriptor object at 0x000001C8A48EDA58> <__main__.Test object at 0x000001C8A48EDEF0> <class '__main__.Test'>
>>> test.x = 'great game'
set <__main__.MyDecriptor object at 0x000001C8A48EDA58> <__main__.Test object at 0x000001C8A48EDEF0> great game
>>> Test
<class '__main__.Test'>
>>> del test.x
delete <__main__.MyDecriptor object at 0x000001C8A48EDA58> <__main__.Test object at 0x000001C8A48EDEF0>
>>>
2.下面 我们来定义一个自己的property
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)
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 = 'X-man'
>>> c.x
'X-man'
>>> c._x
'X-man'
>>> del c.x
>>> c.x
Traceback (most recent call last):
File "<pyshell#100>", line 1, in <module>
c.x
File "<pyshell#92>", line 8, in __get__
return self.fget(instance)
File "<pyshell#94>", line 6, in getx
return self._x
AttributeError: 'C' object has no attribute '_x'
>>>
3.练习 (温度转换)
class Celsius:
def __init__(self,value = 25.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):
return instance.cel * 18 + 32
def __set__(self,instance,value):
instance.cel = (float(value) - 32) / 1.8
class Temperature:
cel = Celsius()
fah = Fahrenheit()
>>> temp = Temperature()
>>> temp.cel
25.0
>>> temp.fah
482.0
>>> temp.cel = 38
>>> temp.fah
716.0
>>>