Python OOP
Python @property Decorator
The @property decorator lets a method be accessed like a plain attribute, giving you the control of a getter/setter pair with the simple syntax of obj.attribute.
From Manual Getters to @property
Earlier, encapsulation examples used get_balance() and set_balance() methods. @property achieves the same protection while letting callers write acc.balance instead of acc.get_balance().
class Account:
def __init__(self, balance):
self.__balance = balance
@property
def balance(self):
return self.__balance
@balance.setter
def balance(self, amount):
if amount < 0:
raise ValueError("Balance cannot be negative")
self.__balance = amount
acc = Account(1000)
print(acc.balance)
acc.balance = 1500
print(acc.balance)1000
1500Computed Properties
A property does not need a matching stored attribute — it can calculate a value on the fly each time it is accessed.
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
r = Rectangle(4, 5)
print(r.area)Read-Only Properties
If you define only the getter with @property and no matching @x.setter, the attribute becomes read-only — trying to assign to it raises an error.
r.area = 100AttributeError: property 'area' of 'Rectangle' object has no setterUse @property whenever you want attribute-style access with validation, computed values, or read-only fields — it keeps your class's public interface clean.
Properties combine well with encapsulation: keep the real data in a private double-underscore attribute and expose it safely through a property.
