Skip to content

Python Getter and Setter Methods: A Comprehensive Guide

Updated: at 04:23 AM

In object-oriented programming, getter and setter methods allow controlled access to an object’s attributes. Getters and setters are also known as accessors and mutators. In Python, getter and setter methods provide an interface for retrieving and updating an object’s state while hiding the implementation details. This encapsulation mechanism helps prevent direct access to object attributes, making the code more robust and maintainable.

This comprehensive guide will explain what getter and setter methods are, why they are used, how to implement them in Python, and provide examples demonstrating their usage. Best practices for designing getter and setter methods will also be covered. By the end, you will have a solid understanding of using getter and setter methods for controlled attribute access in Python.

Table of Contents

Open Table of Contents

What are Getter and Setter Methods?

Getter and setter methods are special methods that provide indirect access to an object’s attributes. Here are their key characteristics:

By convention, getters and setters in Python are named starting with get_ and set_ respectively followed by the attribute name.

Why Use Getter and Setter Methods?

Here are some key reasons to use getter and setter methods in Python:

Overall, getter and setter methods make code more robust, extensible, and maintainable by controlling access to object attributes.

Implementing Getters and Setters in Python

In Python, getter and setter functionality can be implemented using the @property decorator. Here is the general syntax:

class ClassName:

    def __init__(self):
        self._attribute = 0

    @property
    def attribute(self):
        return self._attribute

    @attribute.setter
    def attribute(self, value):
        self._attribute = value

The @property decorator is used to create getter functions that allow attribute access using dot notation like a normal attribute.

The @<attribute>.setter decorator applied on a method converts it to a setter function for that attribute.

Let’s see an example class implementing getter and setter methods:

class Person:

    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise TypeError('Name must be a string')
        self._name = value

person = Person('John')

# Getter usage
print(person.name)

# Setter usage
person.name = 'Sam'

The name attribute is accessed through getter and setter methods instead of directly. This allows validation and constraints to be added like ensuring name is always a string.

Read-Only Attributes

To create a read-only attribute, simply create a getter without a corresponding setter:

class Circle:

    def __init__(self, radius):
        self.radius = radius

    @property
    def diameter(self):
        return 2 * self.radius

Now diameter can be accessed like a normal attribute but cannot be modified as no setter exists.

Derived Attributes

Getters can also compute derived attribute values each time they are accessed:

class Person:

    def __init__(self, age):
        self.age = age

    @property
    def age_in_months(self):
        return self.age * 12

Best Practices for Getters and Setters

Here are some best practices to follow when implementing getter and setter methods in Python:

By properly designing getters and setters methods following best practices, you can create Python classes with controlled attribute access.

Example Use Cases

Here are some examples demonstrating real-world usage of getter and setter methods:

Validating Input

Getters and setters allow validating data before setting it:

class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, value):
        if value < 0:
            raise ValueError('Age cannot be negative')
        self._age = value

person = Person('Mary', -10) # Raises ValueError

Read-only DB ID

For an object fetched from a database, the ID can be read-only while other attributes are changeable:

class DBObject:

    def __init__(self, id, name, value):
        self.id = id
        self.name = name
        self.value = value

    @property
    def id(self):
        return self._id

    @id.setter
    def id(self, value):
        raise AttributeError('ID is read-only')

Derived Attribute

Getters can be used to compute and return derived attributes:

import math

class Circle:

    def __init__(self, radius):
        self.radius = radius

    @property
    def diameter(self):
        return 2 * self.radius

    @property
    def area(self):
        return math.pi * self.radius ** 2

Cached Lookup

For expensive computations, getters can cache the results to avoid recomputing each lookup:

class Image:

    def __init__(self, path):
        self.path = path
        self._size = None

    @property
    def size(self):
        if self._size is None:
            #expensive size lookup
            self._size = get_image_size(self.path)
        return self._size

Conclusion

Getter and setter methods in Python provide controlled attribute access through an interface decoupling object implementation from usage. This leads to more maintainable and robust code.

The @property decorator allows implementing getters and setters elegantly in Python without much boilerplate code. Getters return attribute values while setters modify them.

Key benefits include data validation, derived attributes, read-only attributes, encapsulation, and access control. By following Pythonic best practices for getter and setter design, you can create classes with proper controlled access to attributes.

In summary, getter and setter methods are a crucial object-oriented programming concept in Python enabling encapsulation and access control for maintainable and robust software development.