__slots__.
What is a Descriptor?
A descriptor is any object that defines__get__(), __set__(), or __delete__() methods:
Simple Example
Dynamic Lookups
Descriptors run computations instead of returning constants:Managed Attributes
Control access to instance data with validation:Customized Names
Use__set_name__() to automatically capture attribute names:
Data Validation
Descriptor Types
Data vs Non-Data Descriptors
Data descriptors define both__get__() and __set__():
- Take precedence over instance dictionary
- Used for managed attributes
__get__():
- Instance dictionary takes precedence
- Used for methods and functions
Property Implementation
Here’s how Python’sproperty() works under the hood:
Common Use Cases
Lazy Properties
Compute values only when needed:Type Checking
Best Practices
When to Use Descriptors:
- ✅ Repeated validation logic across multiple classes
- ✅ Computed attributes with caching
- ✅ Attribute access logging/monitoring
- ✅ Type checking and coercion
- ❌ Simple properties (use
@propertyinstead) - ❌ One-off custom behavior (use
__getattribute__override)
Summary
Key points about descriptors:- Define
__get__(),__set__(), or__delete__()to create a descriptor - Use
__set_name__()to capture the attribute name automatically - Data descriptors override instance dictionary
- Non-data descriptors are overridden by instance dictionary
- Descriptors power properties, methods, classmethod, staticmethod, and slots
