马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 向西而笑 于 2017-8-27 10:56 编辑
课时46:描述符(property的原理)
描述符概念
描述符就是将某个特殊类的实例指派给另一个类做属性。 它有一下几个特点:它的实例对象是另一个类的属性;拥有下面例举的方法:
__get__(self,instance,owner):用于访问属性,它返回属性的值 __set__(self,instance,value):将在属性分配操作中调用,不返回任何内容 __delete__(self,instance):控制删除操作,不返回任何内容
以上三个方法属于描述符属性方法。虽然和上节课学的三个方法看起来差不多,但实现起来是两码事 举例:- class Descriptor:
- def __get__(self,instance,owner):
- print('getting...','\n'
- 'self:', self,'\n'
- 'instance:', instance,'\n'
- 'owner:', owner)
- def __set__(self,instance,value):
- print('setting...','\n'
- 'self:', self,'\n'
- 'instance:', instance,'\n'
- 'value:', value)
- def __delete__(self,instance):
- print('deleting...','\n'
- 'self:', self,'\n'
- 'instance:', instance)
复制代码 测试结果:
- >>>class Test:
- x = Descriptor()
- >>> test = Test()
- >>> test.x
- getting...
- self: <__main__.Descriptor object at 0x0100FAB0>
- instance: <__main__.Test object at 0x032BEC10>
- owner: <class '__main__.Test'>
- >>> test.x = 'X-man'
- setting...
- self: <__main__.Descriptor object at 0x0100FAB0>
- instance: <__main__.Test object at 0x032BEC10>
- value: X-man
- >>> del test.x
- deleting...
- self: <__main__.Descriptor object at 0x0100FAB0>
- instance: <__main__.Test object at 0x032BEC10>
复制代码 从上面的例子就能看出:
self的指的是Descriptor的实例对象,也就是x;
instance指的是Test的实例对象,即test
owner指的是Test这个类,它拥有描述符类和描述符对象
定制自己的property
到这里我知道了之前学的内置函数property其实是一个描述符类。知道这个后根据上面的例子,我们可以来定制自己的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 X:
- def __init__(self, initial_value=10):
- self.__example = initial_value #初始一个值为10的属性example
- def x_get(self):
- return self.__example
- def x_set(self,value):
- self.__example = value
- def x_del(self):
- del self.__example
- control = Myproperty(x_get,x_set,x_del) #定义一个属性control,通过control来操作example。相当于给出了一个接口去访问example
复制代码 运行结果:
- >>> t = X()
- >>> t.control
- 10
- >>> t.control = 100
- >>> t.control
- 100
- >>> del t.control
- >>> t.control
- Traceback (most recent call last):
- File "<pyshell#5>", line 1, in <module>
- t.control
- File "C:\Users\Administrator\Desktop\draft\test.py", line 8, in __get__
- return self.fget(instance)
- File "C:\Users\Administrator\Desktop\draft\test.py", line 23, in x_get
- return self.__example
- AttributeError: 'X' object has no attribute '_X__example'</font>
复制代码
温度转换
运用上面学到的定制一个Temprature类,温度可以在摄氏度和华氏度之间自动转换
- class Celcius:
- def __init__(self, value=0):
- self.c_value = float(value)
- def __get__(self,instance,owner):
- return self.c_value
- def __set__(self,instance,value):
- self.c_value = float(value)
-
- class Fahrenheit:
- def __init__(self, value=32):
- self.f_value = float(value)
- 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:
- cel = Celcius()
- fah = Fahrenheit()
复制代码 运行结果:
- >>> temp = Temperature()
- >>> temp.cel
- 0.0
- >>> temp.cel = 100
- >>> temp.cel
- 100.0
- >>> temp.fah
- 212.0
- >>> temp.fah = 100
- >>> temp.cel
- 37.77777777777778
- >>> temp.fah
- 100.0
复制代码
|