Attribute lookup gives data descriptors precedence over instance dictionary entries, while a non-data descriptor can be shadowed by an instance entry.
Python object lookup interview: descriptor precedence before instance state
Operation contract
The receipt object has two descriptor-backed labels. Directly adding a dictionary entry shadows the non-data descriptor but cannot shadow the data descriptor. The program deliberately edits __dict__ to expose lookup order; normal assignment to the read-only data descriptor is rejected. This trace connects properties and methods to the same attribute mechanism.
Failure and ownership boundary
Custom __getattribute__ and __getattr__ hooks can alter behavior, so this fixture covers normal object lookup only. Descriptor lookup is also not a security boundary against code that can directly alter objects. Python descriptors: field validation and attribute precedence and Python staticmethod and classmethod: choose the bound receiver explain when ordinary-looking attribute access runs code.
Working program
class CachedLabel:
def __get__(self, instance, owner):
return "class label"
class RequiredLabel:
def __get__(self, instance, owner):
return "required label"
def __set__(self, instance, value):
raise AttributeError("read-only label")
class ReceiptView:
cached = CachedLabel()
required = RequiredLabel()
receipt = ReceiptView()
receipt.__dict__["cached"] = "instance label"
receipt.__dict__["required"] = "attempted shadow"
print(receipt.cached)
print(receipt.required)
try:
receipt.required = "replacement"
except AttributeError:
print("normal assignment rejected")Output
instance label
required label
normal assignment rejectedCosts and limits
Normal lookup examines class/instance state and the inheritance path, with descriptor execution adding its own cost. A descriptor can perform arbitrary I/O or computation; an attribute’s compact spelling does not make it free.
Common Mistakes
- An instance dictionary entry does not override a data descriptor under normal lookup.
- Attribute access can execute a descriptor method.
Connected lessons
Python descriptors: field validation and attribute precedence, Python properties: validate mutation at the public attribute boundary, Python staticmethod and classmethod: choose the bound receiver.
