python笔记 描述器优先级

53 阅读2分钟

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

0 环境

  • 编辑器:pycharm或者vscode
  • 系统版本:windows10
  • vue版本:2.6.10
  • vxetable版本:v3+

1 参考文章

python描述器

2 关于描述器优先级的问题

现在已知__dict__优先级大于类变量的,那么描述器的优先级是否要高于__dict__

如下代码: 一般都会认为,打印p.d的值应该是100才对,最终值的是24。

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

class Per:
    d = Demo()
    def __init__(self):
        self.d = 24

p = Per()
print(p.d)
print(p.__dict__)

image.png

现在我在Demo加了个__set__,但是里面只有个pass,现在p.d是我们想要的100了,但是__dict__里是空的,是不是说明是因为__set__的缘故呢。 image.png

在改成如下代码: 唯一的改变在Per类里的__init__中,替换成了self.__dict__["d"] = 24

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

    def __set__(self, obj, value):
        pass

class Per:
    d = Demo()
    def __init__(self):
        # self.d = 24
        self.__dict__["d"] = 24

p = Per()
print(p.d)
print(p.__dict__)

image.png

那么__dict__和描述器究竟是怎么样一个关系呢?

当我们调用其他的类,并且是带有__set__或者__delete__方法的描述器,那么该描述器的优先级是高于__dict__,而如果遇到只带有一个__get__方法的描述器,看上面只有__get__方法的描述器的例子,也就说明__dict__优先级大于只有__get__方法的描述器。

3 总结

现在再去回顾一下描述器,首先它的概念是什么呢,或者说什么样的构成就是描述器,简单来说,前提它是一个类,并且在这个类里实现__get____set____delete__方法,任意一个或多个方法(最少实现1个方法,最多这些方法都实现)。之前的操作是通过类变量变向的操作描述器的,当我想访问的时候,xxx.类变量(调用它的__get__方法),当我要赋值的时候,xxx.类变量 = 某个值(调用它的__set__方法)、当我们要删除的时候,用__delete__方法,还有一点,你会发现缺少一个添加方法,为啥没有呢,不可能给一个实例添加个类变量的。