Python › Descriptors & Properties
What is the difference between a data descriptor and a non-data descriptor, and how does this affect attribute lookup priority?
IntermediateAnswer
A DATA descriptor implements BOTH __get__ AND __set__ (or __delete__); a NON-DATA descriptor implements ONLY __get__. Data descriptors take priority OVER an instance's __dict__ during attribute lookup, while non-data descriptors are OVERRIDDEN by an instance's __dict__ if the same name exists there — this priority difference is exactly how @property (a data descriptor) always wins even if you try to shadow it in self.__dict__.
class NonDataDescriptor:
def __get__(self, instance, owner):
return "from descriptor"
class Example:
attr = NonDataDescriptor()
e = Example()
e.__dict__["attr"] = "from instance dict"
print(e.attr) # 'from instance dict' -- instance __dict__ wins for non-data descriptorsReal-world example Understanding why a @property (data descriptor) can't be silently overridden by setting self.__dict__['prop_name'] directly.