走同样的路,发现不同的人生
首先明确:
同时含有__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: instance<-None, owner<-FatherKid.name:instance<-None, owner<-Kidf.name:instance<-f, owner<-Father
首先明确:
同时含有__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: instance<-None, owner<-Father
Kid.name:instance<-None, owner<-Kid
f.name:instance<-f, owner<-Father