@property, setters & computed attributes

Properties and validation

Lesson 10 of 20 · 11 min · Module 3: Objects that behave

Sometimes an attribute must stay valid, or should be calculated from another one. Properties let you keep simple attribute syntax while running code behind it.

Start this lesson →

Free. No installation: you write and run the code in your browser, and it is checked automatically.

By the end, you’ll be able to…

  • Create read-only and computed attributes
  • Validate assignments with a setter
  • Keep one source of truth

The idea

@property turns a method into a read-only attribute. A matching @name.setter runs when someone assigns to it, which is the right place for validation. Store the real value in an attribute with a leading underscore, such as self._celsius.

class Account:
    def __init__(self, balance):
        self.balance = balance

    @property
    def balance(self):
        return self._balance

    @balance.setter
    def balance(self, value):
        if value < 0:
            raise ValueError("balance cannot be negative")
        self._balance = value

01Attribute syntax, method power

Callers write t.fahrenheit, not t.get_fahrenheit(). If the calculation changes later, no calling code has to change.

02Validate in one place

Because __init__ assigns self.celsius = celsius, the setter also checks the starting value. There is no way to create an invalid Temperature.

t = Temperature(10)
t.celsius = 20
print(t.fahrenheit)
Output
68.0

03One stored value

Only _celsius is stored. Fahrenheit is always derived from it, so the two can never disagree. Storing both would invite bugs whenever one is updated without the other.

Your turn

Write a class Temperature. Temperature(25) stores degrees Celsius. The celsius property must reject values below absolute zero (-273.15) with ValueError, including in the constructor. A fahrenheit property returns celsius * 9 / 5 + 32, and assigning to it updates celsius.

What the checks look for

  • Stores celsius and calculates fahrenheit
  • Setting fahrenheit updates celsius
  • Rejects temperatures below absolute zero, also in the constructor
  • Absolute zero itself is allowed
Try it in the editor →

Take this with you

Properties keep attribute syntax while guarding and deriving values.

Go a little further

Add a kelvin property with a setter, reusing the same validation.

Learn Python Intermediate for free

20 short lessons with real code and instant checks.

See the whole course →