Spex3
    

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