Question

Why - or why not - is it good practice to use getters and setters specifically in Python OOP?

My textbook states the following:

import random

class Die(object):
    """Simulate a generic die."""
    def __init__(self):
        self.sides = 6
        self.roll()

    def roll(self):
        """Updates the die with a random roll."""
        self.value = 1+random.randrange(self.sides)
        return self.value

    def getValue(self):
        """Return the last value set by roll()."""
        return self.value

def main():
    d1,d2 = Die(),Die()
    for n in range(12):
        print d1.roll(),d2.roll()

main()

The getValue() method, called a getter or an accessor, returns the value of the value instance variable. Why write this kind of function? Why not simply use the instance variable? We’ll address this in the FAQ’s at the end of this chapter.

However, there is no FAQ at the end of the chapter, and so it is never explained as to why getters are used in Python OOP.

I've tried reading other places, but I have not found a good explanation anywhere. Most answers on SO are about Java, and I've read that it is not relevant to Python...

Can someone please help me understand why it is good practice to use them? Or if not, why not?

Was it helpful?

Solution

Because in Python you have properties:

 class Foo:
   def __init__(self, value):
     self.__value = value

   @property
   def value(self):
     return self.__value

   @value.setter
   def set_value(self, that):
     if that < 0:
       self.__value = 0
     else:
       self.__value = that

Properties make it appear that you are dealing with an attribute but in fact, you're dealing with setters and getters. This allow for better useage of one of Python's defining traits: Duck Typing.

Hence, I can do the following:

 class Bar:
   def __init__(self, value, other):
     self.value = value
     self.other = other

   def __str__(self):
     return ''.join(['Oh joy', str(self.value), str(self.other), '!'])

And then in the function:

 def stuff(x):
   return x.value + 1

I could pass either a type of Bar or a type of Foo and it wouldn't matter. Duck typing would let it "just work."

OTHER TIPS

In Java you should use getters and setters :

It's considered a good practice because it encapsulates your object's inner state, therefore you can change the internals of the object and change the meaning of the value, doing complex things with it without changing its interface.

In python you can use getters and setters :

But it's not that much stressed on for accessing the value of an attribute, because python provides a facility that Java doesn't : properties !

class A(object):
    def __init__(self):
        self._x = 1
    @property
    def x(self):
        return self._x +2
    @x.setter
    def x(self, value):
        self._x = value

This is your built-in syntax to change the meaning of an attribute without changing its interface. And using it is just like using your average attribute syntax.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top