Descriptor protocol
- Python course
- Expert
- Lesson 7/47
- 5 min
Learn descriptors with __get__, __set__, __delete__.
What is the descriptor protocol?
A descriptor is an object that implements at least one of __get__, __set__ or __delete__. When used as a class-level attribute Python routes access through these methods.
For example if you write class Descriptor: def __get__(...) and Box.label = Descriptor(), reading box.label calls __get__. This mechanism underpins property, classmethod and super(). It is handy for validation, computation and caching.
The __get__ signature
The signature is __get__(self, obj, objtype=None): obj is the instance being accessed and objtype is the class.
When accessed on the class (Box.label) obj is None; when accessed on an instance (box.label) obj is that instance. This distinction lets you behave differently at class level vs instance level. Most simple descriptors ignore objtype and only use obj.
Practice Attribute access with a descriptor
Write a Descriptor class. Store the value with __init__(self, value). __get__(self, obj, objtype=None) returns self.value. In a Box class define label = Descriptor("kutu"). Create an instance and print the label attribute.
Starter code
# Write the Descriptor class
# use it in the Box class
# print the valueSample solution
# Write the Descriptor class
class Descriptor:
def __init__(self, value):
self.value = value
def __get__(self, obj, objtype=None):
return self.value
class Box:
label = Descriptor("kutu")
b = Box()
print(b.label)Expected output
kutu
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Which method belongs to the descriptor protocol?
- __get__ Correct answer
- __init__
- __str__
- __repr__
Explanation: __get__ is the read method of the descriptor protocol.
2 Match descriptor methods
| Term | Meaning |
|---|---|
__get__ |
Reading |
__set__ |
Writing |
__delete__ |
Deleting |
descriptor |
Class attribute |
3 Complete the __get__ signature
def __get__(self, obj, ____):
return self.value
def __get__(self, obj, objtype=None):
return self.value
Explanation: objtype defaults to None; it is set during class access.