2

Can you explain the meaning of data hiding here? I also can't understand what does setter do here, and what the code after the setter method does.

My interpretation:

  1. We create an instance called pizza of the class Pizza, with its toppings-attribute equal to the list of strings given by ["cheese", "tomato"].
  2. When we use the code print(pizza.pineapple_allowed), it goes to that property method, making it a read-only attribute, and then returns to self thus returning to False.

I can't understand after that. Please Help!

class Pizza:
  def __init__(self, toppings):
    self.toppings = toppings
    self._pineapple_allowed = False

  @property
  def pineapple_allowed(self):
    return self._pineapple_allowed

  @pineapple_allowed.setter
  def pineapple_allowed(self, value):
    if value:
      password = input("Enter the password: ")
      if password == "Sw0rdf1sh!":
        self._pineapple_allowed = value
      else:
        raise ValueError("Alert! Intruder!")

pizza = Pizza(["cheese", "tomato"])
print(pizza.pineapple_allowed)
pizza.pineapple_allowed = True
print(pizza.pineapple_allowed)
H. Garg
  • 41
  • 4

1 Answers1

1

Getters and setter "hide" a class attribute by wrapping the class attribute and handling the getting and manipulation of this attribute, as opposed to exposing the attribute directly.

The setter (decorated by @pineapple_allowed.setter) in this example restricts the manipulation of the _pineapple_allowed property to people that enter the correct password (Sw0rdf1sh!). If the correct password is not entered an exception is raised, and the attribute will not be altered. While this is just a demonstration (asking for a password that is stored in the source code is not very secure) this does show what setters can be used for: they allow you to implement a check on the value the attribute will be set to, and to do something else than setting the attribute to this value.

For your example, code execution will look something like this:

>>> pizza = Pizza(["cheese", "tomato"])  # create a Pizza instance
>>> print(pizza.pineapple_allowed)  # print the value of pizza._pineapple_allowed
False
>>> pizza.pineapple_allowed = True  # set the value of pizza._pineapple_allowed, this will ask for a password
Enter the password: Sw0rdf1sh!
>>> print(pizza.pineapple_allowed)  # we entered the password, so pizza._pineapple_allowed has been set to True
True

or alternatively, if you enter the wrong password

>>> pizza = Pizza(["cheese", "tomato"])  # create a Pizza instance
>>> print(pizza.pineapple_allowed)  # print the value of pizza._pineapple_allowed
False
>>> pizza.pineapple_allowed = True  # set the value of pizza._pineapple_allowed, this will ask for a password
Enter the password: wrong_password
Traceback (most recent call last):
  File "<stdin>", line 17, in <module>
ValueError: Alert! Intruder!

For more information on getters and setters, this post has a pretty nice overview of reasons to use them.