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'
  • 相关阅读:
    质子喜欢的和他推荐的
    Linux
    Linux
    Spring Boot入门教程1、使用Spring Boot构建第一个Web应用程序
    单点登录(SSO)的设计
    .NET Core快速入门教程 5、使用VS Code进行C#代码调试的技巧
    .NET Core快速入门教程 4、使用VS Code开发.NET Core控制台应用程序
    .NET Core快速入门教程 3、我的第一个.NET Core App (CentOS篇)
    .NET Core快速入门教程 2、我的第一个.NET Core App(Windows篇)
    .NET Core快速入门教程 1、开篇:说说.NET Core的那些事儿
  • 原文地址:https://www.cnblogs.com/paomaliuju/p/5140708.html
Copyright © 2011-2022 走看看