CodeBlanks Logo Icon CodeBlanks

Summary - Descriptors

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

main.py
# Write the Validated descriptor
# use it in the Product class
# print the price

Sample solution

main.py
# 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

Question
class Validated:
    def __set_name__(self, owner, name):
        self.name = name
        self.value = ____
    def __get__(self, obj, objtype=None):
        return self.value
Answer
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.

All lessons in Expert