屬性查找順序
關於屬性描述符請看上文>屬性描述符
在梳理屬性查找相關知識時,查看了很多的書籍和他人的博客,發現很多講的過於抽象,並沒有一個清晰的流程呈現。特此寫下我對於此方面的理解和總結。
我將屬性的查找拆分為三種情形,分別為普通屬性查找、數據描述符查找,非數據描述符查找。
普通屬性的查找
- 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
流程圖
以下為三種情況下的流程圖,為了理解更容易我將三種情況分別講述,在大部分的流程講解中是不為三種情況分別敘述的,容易造成復雜混亂的感覺。