Getters and Setters in Python
Getters and setters are methods used to access and modify the attributes of a class in a controlled manner. They provide encapsulation, allowing you to protect your data by controlling how it is accessed or modified. In Python, you can create getters and setters using traditional methods or the @property decorator. This article explains these concepts with examples.
Why Use Getters and Setters?
Directly accessing attributes of a class is possible in Python, but it is not always ideal. Getters and setters allow you to:
- Validate data before setting it.
- Protect sensitive attributes from being directly modified.
- Add additional logic when getting or setting an attribute.
Traditional Getters and Setters
Example 1: Using Methods for Getters and Setters
class Person:
def __init__(self, name, age):
self.__name = name # Private attribute
self.__age = age # Private attribute
def get_name(self):
return self.__name
def set_name(self, name):
if name:
self.__name = name
else:
print("Invalid name")
def get_age(self):
return self.__age
def set_age(self, age):
if age > 0:
self.__age = age
else:
print("Invalid age")
person = Person("Alice", 30)
print(person.get_name())
person.set_name("Alicia")
print(person.get_name())
print(person.get_age())
person.set_age(35)
print(person.get_age())
In this example, get_name and set_name are used to access and modify the __name attribute, while get_age and set_age do the same for __age.
Using @property Decorator
Python provides a more elegant way to create getters and setters using the @property decorator. This approach allows you to define methods that act like attributes.
Example 2: Using @property
class Rectangle:
def __init__(self, width, height):
self.__width = width
self.__height = height
@property
def width(self):
return self.__width
@width.setter
def width(self, value):
if value > 0:
self.__width = value
else:
print("Width must be positive")
@property
def height(self):
return self.__height
@height.setter
def height(self, value):
if value > 0:
self.__height = value
else:
print("Height must be positive")
rectangle = Rectangle(4, 5)
print(rectangle.width)
rectangle.width = 10
print(rectangle.width)
rectangle.height = -2 # Invalid value
In this example, the width and height properties use the @property and @property_name.setter decorators to define getters and setters.
Benefits of @property
Using @property makes the code more readable and intuitive. It allows you to use getter and setter methods like attributes without parentheses.
Getter-Only Properties
Sometimes, you may want an attribute to be read-only. You can achieve this by defining only the getter method without a setter.
Example 3: Read-Only Attribute
class Circle:
def __init__(self, radius):
self.__radius = radius
@property
def radius(self):
return self.__radius
circle = Circle(5)
print(circle.radius)
# circle.radius = 10 # Raises AttributeError
In this example, the radius attribute is read-only because no setter method is defined.
Combining Getters and Setters
Getters and setters are often combined to manage attributes with additional logic for validation or computation.
Example 4: Combining Getter and Setter
class Employee:
def __init__(self, name, salary):
self.__name = name
self.__salary = salary
@property
def salary(self):
return self.__salary
@salary.setter
def salary(self, value):
if value > 0:
self.__salary = value
else:
print("Salary must be positive")
employee = Employee("John", 5000)
print(employee.salary)
employee.salary = 6000
print(employee.salary)
employee.salary = -1000 # Invalid value
Here, the salary property manages access and modification of the private attribute __salary.
Key Points
- Getters and setters provide controlled access to class attributes.
- Use traditional methods for explicit getter and setter methods.
- Use the
@propertydecorator for a more Pythonic approach. - Define only getter methods for read-only attributes.
Conclusion
Getters and setters are essential for encapsulation in object-oriented programming. Whether using traditional methods or the @property decorator, they ensure data validation, protect sensitive attributes, and provide a cleaner interface for accessing and modifying class attributes.