Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it (or isn't it) good practice to use Getters / Accessors in Python OOP? [duplicate]

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?

like image 981
BBedit Avatar asked Mar 28 '14 14:03

BBedit


People also ask

Why getters and setters are bad?

Getter and setter methods (also known as accessors) are dangerous for the same reason that public fields are dangerous: They provide external access to implementation details. What if you need to change the accessed field's type? You also have to change the accessor's return type.

Should getters and setters be used in Python?

Getters and Setters in python are often used when: We use getters & setters to add validation logic around getting and setting a value. To avoid direct access of a class field i.e. private variables cannot be accessed directly or modified by external user.

Why do we use getters and setters in OOP?

Getters and setters are used to protect your data, particularly when creating classes. For each instance variable, a getter method returns its value while a setter method sets or updates its value. Given this, getters and setters are also known as accessors and mutators, respectively.

What will happen if getters and setters are made private in oops?

The private getter/setter methods provide a place for adding extra behavior or error checking code. They can provide a place for logging state changes or access to the fields.


2 Answers

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."

like image 135
wheaties Avatar answered Nov 15 '22 18:11

wheaties


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.

like image 30
ddelemeny Avatar answered Nov 15 '22 16:11

ddelemeny