描述符

作者: MononokeHime | 来源:发表于2018-07-15 08:46 被阅读0次

描述符的应用

__get__,__getattr____getattribute__都是访问属性的方法,但不太相同。

object.__getattribute__(self, name)
无条件被调用,通过实例访问属性。如果class中定义了__getattr__(),则__getattr__()不会被调用(除非显示调用或引发AttributeError异常)

object.__getattr__(self, name)
当一般位置找不到__attribute__的时候,会调用__getattr__,返回一个值或AttributeError异常。

描述符

如果一个对象或者类中定义了__get____set____delete__其中一个或者几个就称为描述符。

一句话概括:描述符就是可重用的属性

在这里我要告诉你:从根本上讲,描述符就是可以重复使用的属性。也就是说,描述符可以让你编写这样的代码:

f = Foo()
b = f.bar # bar就是一个描述符
f.bar = c
del f.bar

而在解释器执行上述代码时,当发现你试图访问属性(b = f.bar)、对属性赋值(f.bar = c)或者删除一个实例变量的属性(del f.bar)时,就会去调用自定义的方法。

描述符的应用场所

  • 框架,例如django的ORM
  • classmethod,staticmethod,property的实现
  • 缓存,Flask的作者写了一个werkzeug网络工具库中的cached_property

object.__get__(self, instance, owner)
owner是所有者的类,instance是访问descriptor的实例,如果不是通过实例访问,而是通过类访问的话,instance则为None。(descriptor的实例自己访问自己是不会触发__get__,只有descriptor作为其它类的属性才有意义。)(所以下文的d是作为C2的一个属性被调用)

classC(object):
    a='abc'
    def __getattribute__(self,*args,**kwargs):
        print("__getattribute__() is called")
        return object.__getattribute__(self,*args,**kwargs)
#        return "haha"
    def __getattr__(self, name):
        print("__getattr__() is called ")
        return name +" from getattr"
     
    def __get__(self, instance, owner):
        print("__get__() is called", instance, owner)
        return self
     
    def foo(self, x):
        print(x)
 
classC2(object):
    d=C()
if __name__ =='__main__':
    c=C()
    c2=C2()
    print(c.a)
    print(c.zzzzzzzz)
    c2.d
    print(c2.d.a)

输出结果:

__getattribute__() is called
abc
__getattribute__() is called
__getattr__() is called 
zzzzzzzz from getattr
__get__() is called <__main__.C2 objectat 0x16d2310> <class'__main__.C2'>
__get__() is called <__main__.C2 objectat 0x16d2310> <class'__main__.C2'>
__getattribute__() is called
abc

参考:

流程的python
Python 黑魔法 --- 描述器
解密 Python 的描述符

相关文章

  • 如何让对象属性不可配置或枚举

    一、什么是属性描述符? MDN: 对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。 数据描述符是...

  • 如何让对象属性不可配置或枚举

    一、什么是属性描述符? MDN: 对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。 数据描述符是...

  • 定义一个变量

    属性描述符(Property Descriptors) 我们普通的对象属性a的属性描述符(称为“数据描述符”,因为...

  • ios进阶路线 shell脚本语言基础教程(四)

    上篇我们讲了文件描述符还有自定义文件描述符,补充一下如何关闭自定义的文件描述符 语法:exec 描述符>&- 案例...

  • ES8(四) —— Object.getOwnPropertyD

    目录 ES8如何获取Object的描述符设置描述符使用defineProperty()获取单个属性的描述符 —— ...

  • Object.defineProperty方法

    对象的属性在创建的时候,都会带有属性描述符,分为数据描述符和存取描述符 数据描述符是具有值的属性,改属性值可能可写...

  • Java的IO模型

    一.预备知识 1.1 Linux网络IO模型 fd:文件描述符 socketfd:socket描述符 描述符是一个...

  • 对象的属性描述符

    Javascript描述符 属性描述符 value writable enumerable configurabl...

  • python @property

    1.描述符 我们首先要搞懂描述符(Descriptor)是什么. 1.1 描述符定义 只要类中有__get__()...

  • 第三章 文件IO

    对于内核而言,所有打开的文件都通过文件描述符引用,文件描述符是一个非负整数文件描述符标准符号常量文件描述符0标准输...

网友评论

      本文标题:描述符

      本文链接:https://www.haomeiwen.com/subject/ignupftx.html