Python属性的查找顺序
程序员文章站
2022-06-17 11:11:00
属性查找顺序 关于属性描述符请看上文 "属性描述符" 在梳理属性查找相关知识时,查看了很多的书籍和他人的博客,发现很多讲的过于抽象,并没有一个清晰的流程呈现。特此写下我对于此方面的理解和总结。 我将属性的查找拆分为三种情形,分别为普通属性查找、数据描述符查找,非数据描述符查找 ......
属性查找顺序
关于属性描述符请看上文>
在梳理属性查找相关知识时,查看了很多的书籍和他人的博客,发现很多讲的过于抽象,并没有一个清晰的流程呈现。特此写下我对于此方面的理解和总结。
我将属性的查找拆分为三种情形,分别为普通属性查找、数据描述符查找,非数据描述符查找。
普通属性的查找
- normal.py
class myattr(): name = 'class_levy' def __init__(self): self.name = "instance_levy" def __getattribute__(self, item): return "this is getattribute" def __getattr__(self, item): return "this is getattr" my = myattr() print(my.name)
- 我通过上述的代码,一步步的调试,将步骤呈现给读者。当前的输出结果是“this is getattribute"
- 将当前代码中如下的片段注释后,输出结果为"instance_levy"
#def __getattribute__(self, item): #return "this is getattribute"
- 接下来将__init(self)重写如下,输出内容为"class_levy"
def __init__(self): pass
- 最后将类属性注释,输出内容为"this is getattr"
从上述的流程,我们可以分析出普通属性的查找过程为__getattribute__()->实例属性->类属性->getattr
数据描述符的查找
- datades.py
class data(): def __get__(self, instance, owner): return "this is get" def __set__(self, instance, value): pass class myattr(): name = data() def __init__(self): self.name = "instance_levy" def __getattribute__(self, item): return "this is getattribute" def __getattr__(self, item): return "this is getattr" my = myattr() print(my.name)
同上所述的分析方法,我们可以得出查找顺序__getattribute__()->描述符__get__()->实例属性->getattr
非数据描述符的查找
- notdatades.py
class nonedata(): def __get__(self, instance, owner): return "this is get" class myattr(): name = nonedata() def __init__(self): self.name = "instance_levy" def __getattribute__(self, item): return "this is getattribute" def __getattr__(self, item): return "this is getattr" my = myattr() print(my.name)
同上所述的分析方法,我们可以得出查找顺序__getattribute__()->实例属性->描述符__get__()->getattr
流程图
以下为三种情况下的流程图,为了理解更容易我将三种情况分别讲述,在大部分的流程讲解中是不为三种情况分别叙述的,容易造成复杂混乱的感觉。