python笔记 __getattribute__补充和描述器回顾

65 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情

0 环境

  • 编辑器:pycharm或者vscode
  • 系统版本:windows10
  • python版本:3.9.6

1 参考文章

python描述器

2 __getattribute__的优先级

上文都是在类变量下添加个__init__,然后在里面调用__set__,突然想起来还有个狠角色__getattribute__,它是个什么样的存在呢,它的优先级很高,一旦在类变量里面加上,基本是谁来了都不好使。 如下代码:

结合下图,本来我调用p.d的本意是获取到Demo里的__get__方法,但是__getattribute__横刀割爱,直接返回的结果是666。说明优先级__getattribute__更高些。

class Demo:
    def __get__(self, obj, objtype=None):
        return 100

    def __set__(self, obj, value):
        pass

class Per:
    d = Demo()
    
    def __getattribute__(self, name):
        return 666

p = Per()
print(p.d)

image.png

2 回顾__get__

固定的格式,看官方的写法,__get__(self, obj, objtype=None),这里的obj表示的意思是,获取到当前某个类的实例,而objtype表示的意思是类自己,当我们用类直接访问的时候,obj就是空。

3 回顾__set__

固定的格式,看官方的写法,__set__(self, obj, value),根据之前的代码,知道第一个是当前的实例,而第二个表示的是值,还有只有obj实例才可以调用__set__,不得不说的一点,经常会吧实例.类变量 = 值,直接当成是一个简单的变量的赋值,现在才改过来,正常情况下,当出现它的时候,调用__set__,传入(实例,值)。

4 回顾__delete__

固定的格式,看官方的写法是:__delete__(self, obj),它就不用了也知道了吧。怎么用呢,如下图:

image.png

4 总结

撇开刚刚的回顾,想想以前所学的高阶函数的升级版装饰器,是不是也有点像,我调用另一个函数,参数了使用*args,**kwargs接收,而我们这里使用__get____set__这类的接收,在往后是getattr等xxxattr,针对类自身,那么我们调用类是不是也可以用__get____set____delete__,当我指向你的时候,你立马给出我们想要的,在回过来想想,对于我们来说,更加的方便、高效。