84669 person learning
152542 person learning
20005 person learning
5487 person learning
7821 person learning
359900 person learning
3350 person learning
180660 person learning
48569 person learning
18603 person learning
40936 person learning
1549 person learning
1183 person learning
32909 person learning
走同样的路,发现不同的人生
首先明确:
同时含有__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