Lesson 7 of 10

A property that checks its value

Goal

Every new value goes through the check

01

Explanation

A plain attribute like t.celsius is simple, but any line in the program can put -300 in it. @property turns access into a method call while keeping the same syntax. You read the value with t.celsius, and when you write t.celsius = 30 the value goes through a setter, marked with @celsius.setter, that checks it before storing it.

That's why in Python you don't need to write get_ and set_ methods up front. Start with a plain attribute, and when you need validation, turn it into a property: not one line changes for the code that uses the class. A property with no setter is read-only, which suits computed values like fahrenheit.

The trap is that inside the setter you have to store the value under another name, like self._celsius. Write self.celsius = value and the setter calls itself over and over until you hit RecursionError. In __init__, on the other hand, write self.celsius on purpose, so creating the object goes through the same check.

02

Your task

Make celsius in Temperature a property that raises ValueError for any value below -273.15, both on creation and on assignment, and add fahrenheit as a read-only property equal to celsius * 9 / 5 + 32.

Checks

6 checks
  1. celsius reads like a plain attribute
  2. fahrenheit is computed from celsius
  3. fahrenheit follows changes to celsius
  4. Assigning a value below absolute zero raises ValueError and keeps the old value
  5. Creating one with an impossible value is rejected too
  6. fahrenheit is read-only
main.py
OutputPython (Pyodide)

Loading Python. This only happens once. Your browser keeps it after that.

–/6

Checks start once the environment is ready.

6 checks listed under “Your task”.