typestar

Descriptors in Python

The protocol properties are built on: __get__ and __set__ on a class attribute.

class Bounded:
    def __init__(self, low, high):
        self.low = low
        self.high = high

    def __set_name__(self, owner, name):
        self.store = "_" + name

    def __get__(self, instance, owner=None):
        if instance is None:
            return self
        return getattr(instance, self.store)

    def __set__(self, instance, value):
        if not self.low <= value <= self.high:
            raise ValueError(f"{value} outside {self.low}..{self.high}")
        setattr(instance, self.store, value)


class Step:
    stars = Bounded(0, 3)


step = Step()
step.stars = 3
print(step.stars)

How it works

  1. __set_name__ learns the attribute name it was assigned to.
  2. One descriptor instance serves every instance of the owner.
  3. This is how properties, methods and slots all work underneath.

Keywords and builtins used here

The run, in numbers

Lines
26
Characters to type
510
Tokens
153
Three-star pace
105 tpm

At the three-star pace of 105 tokens a minute, this run takes about 87 seconds.

Type this snippet

Step 3 of 3 in Attributes & descriptors, step 34 of 53 in Pythonic Python.

← Previous Next →