This puzzle introduces Python’s powerful descriptor protocol and the use of property decorators to control attribute access in a class.

Topics Covered

  • Descriptors (__get__, __set__)
  • Property decorators (@property, @<name>.setter)
  • Encapsulation and computed properties

Puzzle Question

How does Python decide what code runs when you access or assign to an attribute? What will the following code output?

Puzzle Code

class Celsius:
    def __init__(self, temperature=0):
        self._temperature = temperature

    @property
    def temperature(self):
        print("Getting value...")
        return self._temperature

    @temperature.setter
    def temperature(self, value):
        print("Setting value...")
        if value < -273.15:
            raise ValueError("Temperature below absolute zero!")
        self._temperature = value

temp = Celsius()
temp.temperature = 25
print(temp.temperature)
temp.temperature = -300

Hints

  1. The @property decorator turns a method into a getter.
  2. The @<name>.setter decorator turns a method into a setter for that property.
  3. The setter can enforce logic or validation before changing the internal value.

Answer

Setting value...
Getting value...
25
Setting value...
Traceback (most recent call last):
  ...
ValueError: Temperature below absolute zero!

Explanation:

  • The first assignment to temp.temperature calls the setter method and sets the value after printing "Setting value...".
  • The call to print(temp.temperature) invokes the getter, which prints "Getting value..." and returns 25.
  • The second assignment triggers the setter again, but since the value is below absolute zero, it raises a ValueError.

Learnings

  • Descriptors Under the Hood: The @property decorator is syntactic sugar for using Python’s descriptor protocol (__get__, __set__, __delete__).
  • Encapsulation: Property decorators allow you to encapsulate access logic without changing how the attribute is used externally.
  • Validation and Safety: Setters provide a clean way to include validation logic during assignment.