zoukankan      html  css  js  c++  java
  • Python描述符:property()函数的小秘密

    描述符:将某种特殊类型的类的实例指派给另一个类的属性(注意:这里是类属性,而不是对象属性)。而这种特殊类型的类就是实现了__get__,__set__,__delete__这三个方法中的一个或多个的新式类(即继承object)。其中,__get__,__set__,__delete__与__getattr__,__setattr__,__delattr__是很相似的,但是前面3个我们称之为属于描述符的属性方法。

    __get__(self, instance, owner)
    - 用于访问属性,它返回属性的值
    __set__(self, instance, value)
    - 将在属性分配操作中(赋值)调用,不返回任何内容
    __delete__(self, instance)
    - 控制删除操作,不返回任何内容

    class MyDescriptor:
        def __get__(self, instance, owener):
            print('getting...', self, instance, owener)
        def __set__(self, instance, value):
            print('settiong...', self, instance, value)
        def __delete__(self, instance):
            print('deleting...', self, instance)
    
    class Test:
        x = MyDescriptor()
    
    >>> test = Test()
    >>> test.x
    getting... <__main__.MyDescriptor object at 0x0000000002D6A6A0> <__main__.Test object at 0x0000000002D886A0> <class '__main__.Test'>
    >>> test
    <__main__.Test object at 0x0000000002D886A0>
    >>> Test
    <class '__main__.Test'>

    以上代码中,MyDescriptor类就是描述符类。其中__get__,__set__,__delete__方法中的self是指MyDescriptor类本身的实例对象;instance参数是指属性拥有者的类的实例(本例中是test);__get__第三个参数owner是指属性拥有者的类对象本身(本例中是Test)。其实,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 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'
    >>> del c.x
    >>> c.x
    Traceback (most recent call last):
      File "<pyshell#79>", line 1, in <module>
        c.x
      File "<pyshell#72>", line 7, in __get__
        return self.fget(instance)
      File "<pyshell#74>", line 5, in getX
        return self._x
    AttributeError: 'C' object has no attribute '_x'
  • 相关阅读:
    自制404页面
    Http错误代码含义
    数据访问基础类(基于Access数据库)
    NTILE函数在SQL Server 2000中的实现方法
    矩阵螺旋输出
    分区排名方案和排名值效率分析【图文+测试代码】
    安装eclipse axis2 插件(links 方式)
    perforce关闭服务后无法重启
    A4纸网页打印中对应像素的设定和换算
    2005数据库脚本在SQL2000上执行
  • 原文地址:https://www.cnblogs.com/paomaliuju/p/5140708.html
Copyright © 2011-2022 走看看