马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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
|