鱼C论坛

 找回密码
 立即注册
查看: 1583|回复: 0

[技术交流] 十一章节:描述符(property原理)

[复制链接]
发表于 2017-8-27 10:54:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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






评分

参与人数 1鱼币 +7 收起 理由
小甲鱼 + 7

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 10:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表