According to Python's documentation,
Data descriptors with
__set__()and__get__()defined always override a redefinition in an instance dictionary.
I have no problem understanding this sentence, but can someone clarify for me why such a rule is in place? After all, if I want to override an attribute in an instance dictionary, I already need to do that explicitely (inst.__dict__["attr"] = val), as a naive inst.attr = val would call the descriptor's __set__ method, which would (usually) not override the attribute in the instance dictionary.
edit: just to make it clear, I understand what is happening, my question is about why such a rule was put in place.
The override applies to descriptors that are part of the class
__dict__.Python will always look up
type(instance).__dict__[attributename].__get__(instance, type(instance)), and will not useinstance.__dict__to search for a instance-override.Here is an example using a contrived
Descriptorclass and a property (which is a descriptor with a__get__and a__set__:As you can see, even though I add a
spamentry in the instance__dict__, it is completely ignored and theFoo.spamproperty is used still. Python is ignoring the instance__dict__because thespamproperty defines both__get__and a__set__.If you use a descriptor that doesn't define a
__set__the override works (but it's__get__is not called: