A descriptor that contains both __get__ and __set__ methods is calleddata descriptor
A descriptor that only contains the __get__ method is called anon-data descriptor
Then clarify the order of attribute search in python, taking obj.attr as an example:
If attr is __class__, __doc__ and other attributes in dir(obj), then find it directly;
Look for thedata descriptornamed attr in obj.__class__.__dict__. If found, it will return attr.__get__(obj, obj.__class__). If it is not found, it will continue to search in the parent class and ancestor class of obj. data descriptor;
Search in obj.__dict__. If obj is a common instance, return directly if found, otherwise proceed to the next step; if obj is a class, then search for descriptor in obj.__dict__. If found, return attr.__get__(None, obj), not found, will continue to look for descriptor in the parent class and ancestor class
Findnon-data descriptorin obj.__class__.__dict__ and return attr.__get__(obj, obj.__class__);
Look for common attributes in obj.__class__.__dict__ and return them directly if found;
The attr attribute cannot be found and an exception is thrown
According to the above search sequence, we can know: Father.name: instance<-None, owner<-Father Kid.name: instance<-None, owner<-Kid f.name:instance<-f, owner<-Father
First of all, let’s be clear:
A descriptor that contains both __get__ and __set__ methods is calleddata descriptor
A descriptor that only contains the __get__ method is called anon-data descriptor
Then clarify the order of attribute search in python, taking obj.attr as an example:
If attr is __class__, __doc__ and other attributes in dir(obj), then find it directly;
Look for thedata descriptornamed attr in obj.__class__.__dict__. If found, it will return attr.__get__(obj, obj.__class__). If it is not found, it will continue to search in the parent class and ancestor class of obj. data descriptor;
Search in obj.__dict__. If obj is a common instance, return directly if found, otherwise proceed to the next step; if obj is a class, then search for descriptor in obj.__dict__. If found, return attr.__get__(None, obj), not found, will continue to look for descriptor in the parent class and ancestor class
Findnon-data descriptorin obj.__class__.__dict__ and return attr.__get__(obj, obj.__class__);
Look for common attributes in obj.__class__.__dict__ and return them directly if found;
The attr attribute cannot be found and an exception is thrown
According to the above search sequence, we can know:
Father.name: instance<-None, owner<-Father
Kid.name: instance<-None, owner<-Kid
f.name:instance<-f, owner<-Father