走同样的路,发现不同的人生
首先明確:
同時含有__get__, __set__方法的descriptor叫做data descriptor
只含有__get__方法的descriptor叫做non-data descriptor
接著在明確一下python中的屬性尋找順序,以obj.attr為例:
如果attr是__class__, __doc__等這些在dir(obj)中的屬性,那麼直接找到;
在obj.__class__.__dict__中找名為attr的data descriptor, 找到返回attr.__get__(obj, obj.__class__),沒找到,會繼續在obj的父類及祖先類中尋找data descriptor;
在obj.__dict__中查找,如果obj是一個普通實例,找到直接返回,否則進行下一步;如果obj是一個class,那麼會在obj.__dict__找descriptor,如果找到則返回attr.__get__( None, obj),沒找到,會繼續在父類及祖先類中找descriptor
在obj.__class__.__dict__中查找non-data descriptor,回傳attr.__get__(obj, obj.__class__);
在obj.__class__.__dict__中找普通屬性,找到直接回傳;
找不到attr屬性,拋異常
依以上查找順序,可知:Father.name: instanceKid.name:instancef.name:instance
首先明確:
同時含有__get__, __set__方法的descriptor叫做data descriptor
只含有__get__方法的descriptor叫做non-data descriptor
接著在明確一下python中的屬性尋找順序,以obj.attr為例:
如果attr是__class__, __doc__等這些在dir(obj)中的屬性,那麼直接找到;
在obj.__class__.__dict__中找名為attr的data descriptor, 找到返回attr.__get__(obj, obj.__class__),沒找到,會繼續在obj的父類及祖先類中尋找data descriptor;
在obj.__dict__中查找,如果obj是一個普通實例,找到直接返回,否則進行下一步;如果obj是一個class,那麼會在obj.__dict__找descriptor,如果找到則返回attr.__get__( None, obj),沒找到,會繼續在父類及祖先類中找descriptor
在obj.__class__.__dict__中查找non-data descriptor,回傳attr.__get__(obj, obj.__class__);
在obj.__class__.__dict__中找普通屬性,找到直接回傳;
找不到attr屬性,拋異常
依以上查找順序,可知:
Father.name: instanceKid.name:instancef.name:instance