@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)68.003One 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
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
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.