Getter and Setter methods
When you make an attribute private (like using __
_
- Getter: A method to read (get) the value of a private attribute.
- Setter: A method to modify (set) the value of a private attribute.
Why use Getters and Setters?
You might ask, "Why not just use public attributes?" Here's why:
- Getters and setters let you control how attributes are accessed or changed. For example:
- Only allow positive values.
- Perform a calculation before setting a value.
- They protect your data by hiding the implementation details and exposing only what’s needed.
- Validation: You can add checks (e.g., "Don’t allow a negative age!") when setting a value.
How do they work?
Here’s a step-by-step example:
Without Getters and Setters: Let’s say we have a Person
class:
Person
class Person:
def __init__(self, name, age):
self.__name = name # Private attribute
self.__age = age # Private attribute
If you try to access the private attributes:
person = Person("Alice", 25)
print(person.__age) # Error: You can't access private attributes!
With Getters and Setters: We define getter and setter methods to access and modify the private attributes safely:
class Person:
def __init__(self, name, age):
self.__name = name
self.__age = age
# Getter for 'age'
def get_age(self):
return self.__age
# Setter for 'age'
def set_age(self, new_age):
if new_age > 0: # Validation: Age must be positive
self.__age = new_age
else:
print("Age must be positive!")
Now you can interact with the private __age
person = Person("Alice", 25)
# Get the age
print(person.get_age()) # Output: 25
# Set a new age
person.set_age(30)
print(person.get_age()) # Output: 30
# Try to set a negative age
person.set_age(-5) # Output: Age must be positive!
Using @property
for a cleaner approach
@property
Python provides a built-in way to create getters and setters more cleanly using the @property
How it works:
: Makes a method behave like a getter.@property
: Defines the setter for the same property.@ .setter
Here’s the same example using @property
class Person:
def __init__(self, name, age):
self.__name = name
self.__age = age
# Getter for 'age'
@property
def age(self):
return self.__age
# Setter for 'age'
@age.setter
def age(self, new_age):
if new_age > 0:
self.__age = new_age
else:
print("Age must be positive!")
Using @property
:
@property
person = Person("Alice", 25)
# Get age (looks like an attribute, but calls the getter)
print(person.age) # Output: 25
# Set age (calls the setter)
person.age = 30
print(person.age) # Output: 30
# Try to set a negative age
person.age = -5 # Output: Age must be positive!
Key differences between the two approaches
Traditional Method | Using @property |
---|---|
Use explicit get_* set_* |
Access like a normal attribute |
Example: person.get_age() |
Example: person.age |
Clearer for beginners | Cleaner and Pythonic |
When should you use Getters and Setters?
- Protect sensitive data: Keep attributes private and control their access.
- Add rules: Validate data before allowing changes.
- Future-proof your code: Even if you don’t need getters/setters now, adding them later is easier with
.@property
Key points to remember:
Think of a private attribute like a safe in your house:
- The getter is the key that lets you open the safe to see what’s inside.
- The setter is a way to control what can go inside the safe (e.g., only allow items that fit).