Descriptors in Python are a powerful feature that allows developers to customize attribute access, making them essential for advanced object-oriented programming. This guide explores descriptors in depth, from basics to examples, and includes practical applications, advantages, disadvantages, and interview questions.
What Are Descriptors in Python?
Descriptors are objects in Python that define how an attribute is accessed, modified, or deleted. They are used to manage attribute behavior dynamically and can be implemented by defining any of the following methods in a class:
__get__(self, instance, owner)
__set__(self, instance, value)
__delete__(self, instance)
Descriptors enable the customization of an object’s behavior when its attributes are accessed.

Why Use Descriptors in Python?
- Custom Attribute Management: Control how attributes are set, retrieved, or deleted.
- Reusability: Define behavior once and reuse it across multiple classes.
- Enhanced Encapsulation: Enforce constraints on attributes.
- Integration: Used internally by properties, methods, and staticmethods in Python.
Types of Descriptors in Python
- Data Descriptors
Define both__get__()
and__set__()
methods. These descriptors override instance dictionaries. - Non-Data Descriptors
Define only the__get__()
method. These allow instance attributes to override them.
How Descriptors in Python Work
Descriptors are invoked through the descriptor protocol. When an attribute is accessed, Python checks for a descriptor in the class dictionary before falling back to the instance dictionary.
Descriptors in Python Examples
1. A Simple Descriptor
class DescriptorExample: def __get__(self, instance, owner): print("Getting value") return instance._value def __set__(self, instance, value): print("Setting value") instance._value = value def __delete__(self, instance): print("Deleting value") del instance._value class MyClass: attribute = DescriptorExample() obj = MyClass() obj.attribute = 10 # Setting value print(obj.attribute) # Getting value del obj.attribute # Deleting value
2.Descriptor for Attribute Validation
class PositiveValue: def __set__(self, instance, value): if value < 0: raise ValueError("Value must be positive") instance._value = value def __get__(self, instance, owner): return instance._value class Account: balance = PositiveValue() acct = Account() acct.balance = 100 # Valid print(acct.balance) # 100 acct.balance = -50 # Raises ValueError
3.Reusable Descriptors for Multiple Classes
class Typed: def __init__(self, type_): self.type_ = type_ def __set__(self, instance, value): if not isinstance(value, self.type_): raise TypeError(f"Expected {self.type_}") instance.__dict__[self.name] = value def __get__(self, instance, owner): return instance.__dict__.get(self.name) def __set_name__(self, owner, name): self.name = name class Person: name = Typed(str) age = Typed(int) p = Person() p.name = "John" # Valid p.age = 25 # Valid p.age = "Twenty-five" # Raises TypeError
Advantages of Using Descriptors
- Customization: Fine-tune how attributes behave dynamically.
- Reusability: Write once, use in multiple classes.
- Encapsulation: Enforce strict rules on attribute access.
- Interoperability: Combine with properties, decorators, and meta classes.
Disadvantages of Using Descriptors
- Complexity: Adds complexity to the code, which can confuse beginners.
- Performance: Slightly slower than direct attribute access due to method calls.
- Debugging: Errors in descriptor logic can be harder to track down.
Common Use Cases of Descriptors in Python
- Attribute Validation: Ensure data integrity.
- Lazy Loading: Initialize attributes only when accessed.
- Caching: Store computed values for reuse.
- ORMs: Used in frameworks like SQLAlchemy for dynamic attribute management.
Conclusion
Descriptors in Python provide a robust way to customize attribute behavior and are an essential feature for advanced Python programming. While they require a deeper understanding of Python’s object model, mastering them opens up new possibilities for reusable and maintainable code.
Interview Questions
1. What is the difference between data and non-data Descriptors in Python?
Answer:
- Data descriptors define both
__get__
and__set__
methods, overriding instance attributes. - Non-data descriptors define only
__get__
, allowing instance attributes to override them.
2. How are descriptors used in Python’s built-in features?
Answer: Descriptors are used to implement built-in features like properties (@property
), methods, and staticmethods.
3. What is the purpose of the __set_name__
method in descriptors?
Answer: The __set_name__
method is called automatically when the descriptor is assigned to a class attribute. It allows the descriptor to know the name of the attribute it manages.
4. Can descriptors replace properties?
Answer: Yes, descriptors can achieve everything that properties do but are more reusable and flexible when applied across multiple attributes or classes.
5. When should you avoid using descriptors?
Answer: Avoid using descriptors for simple tasks where properties or instance attributes are sufficient, as they add unnecessary complexity.
QUIZZES
Descriptors Quiz
Question
Your answer:
Correct answer:
Your Answers