Getters and Setters in Python (Using property) 🏡🐍

Getters and Setters are used to control access to class attributes, ensuring data encapsulation and validation.
🔹 Getter: Retrieves the value of an attribute.
🔹 Setter: Updates/modifies the value of an attribute, often with validation.
Python provides two ways to implement getters and setters:
✅ Using getter and setter methods
✅ Using the @property decorator (recommended)
1️⃣ Traditional Getters and Setters (Without @property)
class Employee:
def __init__(self, name, salary):
self.name = name
self.__salary = salary # Private attribute
# Getter method
def get_salary(self):
return self.__salary
# Setter method
def set_salary(self, new_salary):
if new_salary > 0: # Validation
self.__salary = new_salary
else:
raise ValueError("Salary must be positive")
emp = Employee("Alice", 5000)
print(emp.get_salary()) # ✅ Access via getter
emp.set_salary(6000) # ✅ Modify via setter
print(emp.get_salary())
# emp.__salary = 10000 ❌ Does not change private variable
🔹 Drawback: The syntax requires get_salary() and set_salary(), making it less intuitive.
2️⃣ Using @property (Recommended Approach)
Python provides the @property decorator, allowing attributes to be accessed like regular variables while keeping encapsulation.
class Employee:
def __init__(self, name, salary):
self.name = name
self.__salary = salary # Private attribute
@property # Getter
def salary(self):
return self.__salary
@salary.setter # Setter
def salary(self, new_salary):
if new_salary > 0: # Validation
self.__salary = new_salary
else:
raise ValueError("Salary must be positive")
emp = Employee("Bob", 5000)
print(emp.salary) # ✅ No need for () – acts like an attribute
emp.salary = 7000 # ✅ Uses the setter
print(emp.salary)
# emp.salary = -2000 ❌ Raises ValueError: Salary must be positive
🔹 Advantages of @property:
✅ No need to call methods explicitly (emp.salary instead of emp.get_salary()).
✅ Allows read-only properties if no setter is defined.
✅ Improves code readability and maintains encapsulation.
3️⃣ Read-Only Properties (No Setter)
📌 If we only define a getter (@property) without a setter, the attribute becomes read-only.
class Car:
def __init__(self, model, speed):
self.model = model
self.__speed = speed # Private
@property
def speed(self):
return self.__speed # Read-only
car = Car("Tesla", 200)
print(car.speed) # ✅ Allowed
car.speed = 250 # ❌ AttributeError: can't set attribute
🔹 The speed attribute can be read but not modified.
4️⃣ Using @property with a Deleter (@salary.deleter)
📌 We can also delete an attribute using a deleter.
class Employee:
def __init__(self, name, salary):
self.name = name
self.__salary = salary
@property
def salary(self):
return self.__salary
@salary.deleter
def salary(self):
del self.__salary # Deletes the attribute
emp = Employee("Charlie", 8000)
print(emp.salary) # ✅ 8000
del emp.salary # ✅ Deletes the salary attribute
# print(emp.salary) ❌ AttributeError: 'Employee' object has no attribute '__salary'
🔹 del emp.salary removes the private __salary attribute.
5️⃣ Summary Table
Approach Description Example
Traditional Getters/Setters Uses get_ and set_ methods explicitly get_salary() / set_salary()
@property Decorator (Recommended) Allows attributes to be accessed like normal variables @property for getter,
@salary.setter for setter
Read-Only Property Defines a property without a setter @property only
Using Deleter (@deleter) Allows deletion of an attribute @salary.deleter
6️⃣ When to Use Getters and Setters?
✅ To protect private attributes from accidental modification.
✅ To add validation before updating values (e.g., salary must be positive).
✅ To make attributes read-only (getter only, no setter).
✅ To maintain backward compatibility when changing the internal implementation.
Date: 2025-03-24 00:00:00.000000