Python Advance Course
Property Decorators in Python (@property, @setter, @deleter)
Property Decorators in Python (@property, @setter, @deleter)
Property decorators allow you to control how class attributes are accessed, modified, and deleted while keeping a clean syntax.
They help you:
- Protect data (encapsulation)
- Add validation logic
- Keep attribute-style access (obj.value) instead of method calls
Why Property Decorators?
Without property:
obj.get_value()
obj.set_value(10)
With property:
obj.value
obj.value = 10
Cleaner, safer, more Pythonic.
1. @property (Getter)
Used to access a method like an attribute.
Example:
class Student:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
s = Student("Aman")
print(s.name)
Output:
Aman
Real World Example
Bank balance (read-only access):
class BankAccount:
def __init__(self, balance):
self._balance = balance
@property
def balance(self):
return self._balance
acc = BankAccount(5000)
print(acc.balance)
Graph (Flow)
obj.balance
↓
@property method runs
↓
returns value safely
Common Mistake
class A:
@property
def value(self):
return 10
a = A()
print(a.value())
Error: - property is not callable
Correct:
print(a.value)
Homework 1
Create a class Product with a read-only price property.
Solution:
class Product:
def __init__(self, price):
self._price = price
@property
def price(self):
return self._price
p = Product(100)
print(p.price)
2. @setter (Setter)
Used to modify a property safely.
Example:
class Student:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
s = Student("Aman")
s.name = "Ravi"
print(s.name)
Output:
Ravi
Real World Example
User password validation:
class User:
def __init__(self, password):
self._password = password
@property
def password(self):
return "****"
@password.setter
def password(self, value):
if len(value) < 6:
print("Weak password")
else:
self._password = value
u = User("123456")
u.password = "abc"
Graph
obj.value = 10
↓
@setter validation runs
↓
value stored safely
Common Mistake
class A:
@property
def x(self):
return 10
@x.setter
def x(self, value):
self.x = value
Problem: - infinite recursion
Correct:
self._x = value
Homework 2
Create a class Employee with salary validation:
- salary must be > 0
Solution:
class Employee:
def __init__(self, salary):
self._salary = salary
@property
def salary(self):
return self._salary
@salary.setter
def salary(self, value):
if value <= 0:
print("Invalid salary")
else:
self._salary = value
e = Employee(1000)
e.salary = 2000
print(e.salary)
3. @deleter (Delete Property)
Used to delete an attribute safely.
Example:
class Student:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.deleter
def name(self):
print("Deleting name")
del self._name
s = Student("Aman")
del s.name
Output:
Deleting name
Real World Example
Account deletion:
class Account:
def __init__(self, user):
self._user = user
@property
def user(self):
return self._user
@user.deleter
def user(self):
print("Account removed")
del self._user
Graph
del obj.value
↓
@deleter method runs
↓
cleanup happens
Common Mistake
del obj.value()
Error: - property is not callable
Correct:
del obj.value
Homework 3
Create a class File:
- property name
- allow deletion with message "File deleted"
Solution:
class File:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.deleter
def name(self):
print("File deleted")
del self._name
f = File("data.txt")
del f.name
Summary Table
| Decorator | Purpose | Example |
|---|---|---|
| @property | getter | access value safely |
| @setter | modify value | validation logic |
| @deleter | delete value | cleanup |
Real World Mapping
| Feature | Real Example |
|---|---|
| property | bank balance view |
| setter | password update |
| deleter | account deletion |
Property Flow Diagram
GET → @property
SET → @setter
DEL → @deleter
Full Example (All Together)
class User:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
@name.deleter
def name(self):
del self._name
u = User("Aman")
print(u.name)
u.name = "Ravi"
del u.name
Common Mistakes Summary
- Using function call on property (
obj.name()) - Recursive setter (
self.name = value) - Forgetting underscore storage (
self._name)
Next Advanced Topics
- Descriptors in Python
- OOP Encapsulation deep dive
- Magic methods (__get__, __set__)
- Data Classes (@dataclass)
- Abstract Base Classes (ABC)
- Advanced OOP design patterns ```