Summary - Descriptors
- Python course
- Expert
- Lesson 12/47
- 5 min
Combine __get__, __set__ and __set_name__ to write a Validated descriptor.
Recap: descriptors
In this group you learned the descriptor protocol. __get__ intercepts reads, __set__ writes, __delete__ deletes. A data descriptor implements both __get__ and __set__; a non-data descriptor only __get__.
You saw that @property is a data descriptor. With __set_name__ the descriptor learns its name. Now you will combine these into a Validated descriptor: store the name with __set_name__, return the value with __get__, reject negatives with __set__. This is a realistic validation layer.
Practice Write a Validated descriptor
Write a Validated descriptor. In __set_name__(self, owner, name) set self.name = name and self.value = 0. __get__(self, obj, objtype=None) returns self.value. In __set__(self, obj, value) raise ValueError if the value is less than 0; otherwise set self.value = value. In a Product class define price = Validated(). Create an instance, set price = 100 and print it.
Starter code
# Write the Validated descriptor
# use it in the Product class
# print the priceSample solution
# Write the Validated descriptor
class Validated:
def __set_name__(self, owner, name):
self.name = name
self.value = 0
def __get__(self, obj, objtype=None):
return self.value
def __set__(self, obj, value):
if value < 0:
raise ValueError("negative")
self.value = value
class Product:
price = Validated()
p = Product()
p.price = 100
print(p.price)Expected output
100
What you learned
In this group you learned one of Python's most powerful features: the descriptor protocol. You intercepted attribute access with __get__, __set__ and __delete__. You saw the priority difference between data and non-data descriptors.
You learned that @property is a data descriptor behind the curtain. You added name awareness with __set_name__. In the summary you combined three methods into a Validated descriptor. This knowledge is key to understanding how Python frameworks work.
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Which type of descriptor?
- a data descriptor only implements __get__
- property is non-data
- a non-data is overridden by the instance dict Correct answer
- __set_name__ fires at instance level
Explanation: answer: a non-data is overridden by the instance dict. Without __set__ it does not intercept writes.
2 Match all descriptor concepts
| Term | Meaning |
|---|---|
__get__ |
Reading |
__set__ |
Writing |
__set_name__ |
Name notification |
property |
Data descriptor |
3 Final blank
class Validated:
def __set_name__(self, owner, name):
self.name = name
self.value = ____
def __get__(self, obj, objtype=None):
return self.value
class Validated:
def __set_name__(self, owner, name):
self.name = name
self.value = 0
def __get__(self, obj, objtype=None):
return self.value
Explanation: self.value = 0 sets the initial value.