-1

im a new python programmer and I recently started learning about @property and the @setter decorators in python. However I am confused about their use in the simplest scripts for example:

class Aaron:
    def __init__(self,name):
       self.name = name
    @property
    def name(self):
       return self._name
    @name.setter
    def name(self,new):
        self._name = new

what is the use of setters and getters?, any help is appreciated Thanks

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
Aaron B
  • 49
  • 4
  • 1
    the `property` decorator and descriptors in general are how Python does data-hiding/encapsulation. Instead of having to write a bunch of biolerplate getters and setters, you can start off with simple attribute access and then refractor to use a managed attribute with `property` without breaking your previous code. So, in this case specifically, you wouldn't use them – juanpa.arrivillaga Mar 07 '18 at 01:08
  • Hi sorry to disturb you, but could you explain the setters and getters in an easier way, i had trouble understanding what you wrote about it, thanks – Aaron B Mar 07 '18 at 01:11
  • Let's say for your name property, you want to raise an exception if the name contains numbers in it. `property` would allow you to do string/type checking before assigning it to an internal variable. – NinjaKitty Mar 07 '18 at 01:12
  • @AaronB you are going to have to give more background about exactly what you don't understand. It sounds like perhaps you would be better off reading an introdutory OOP tutorial, ideally one geared towards Pytho so that you actually learn about `property`, often, OOP tutorials in Python will use java-like `get_attr` nd `set_attr` methods which are not pythonic – juanpa.arrivillaga Mar 07 '18 at 01:12
  • @AaronB Basically you want to give the user of your class the possibility to change the value of a property, but when doing so you 1) want to validate that change before doing it, or 2) trigger events that are necessary on the change of this property. So you need to use a getter/setter so that this can be managed. – Havenard Mar 07 '18 at 01:13
  • oh i get it now, so property allows you to return the instances attribute but the setter allows you to check to make sure the attribute follows certain criteria through an if statement before the attribute is changed? – Aaron B Mar 07 '18 at 01:14
  • Basically, yes. While getters generally just straight up return you the value, the setters tend to be more elaborated. – Havenard Mar 07 '18 at 01:14

2 Answers2

3

Getters and Setters are simply methods that aid in encapsulation. They are not specific to Python but rather Object-Oriented Programming in general;

They are alternatively called mutator/accessor methods.

What's their point?

They hide implementation details

Users of your class don't need to know the property name you are using internally to keep track of the name of your User. You just tell them to call .getName() to get the name and that's it.

They allow you to add validation checks

Had the property been exposed for you to arbitrarily change, without using a set method, you could have made erroneous changes, e.g setting the name of your User instance to '12'.

You can perform other work before you actually mutate a property

Sometimes you may want to keep a history of the mutations that took place on your instance. Using a setter allows you to trigger other functions before actually changing the property value, for example calling a logNameChanges method.

These are the most important reasons I've ever practically came across. There's a more exhaustive list here.

nicholaswmin
  • 21,686
  • 15
  • 91
  • 167
  • Umm... You do not tell them to call `.getName()`, that's Java nonsense. The whole point of `@property` is that it can make something that is used like an attribute, but can do the work of a method. In particular, you *don't* typically use encapsulation to start with (a plain `name` attribute is considered perfectly Pythonic if no programmatic behaviors are needed), but if you later decide you need it to do some validation or other work, you can retroactively change the actual attribute to, say, `_name`, then define `name` as a `@property`, and the interface for users remains identical. – ShadowRanger Mar 07 '18 at 02:02
  • @ShadowRanger Great, feel free to edit that part of the answer. – nicholaswmin Mar 07 '18 at 02:04
  • You also missed one common use, which is to define `@property` without a `setter`/`deleter`, to make "read only" attributes. Since it's Python, they're not really read only (unless you're using a `namedtuple` setup), since the underlying real attribute is mutable, but if you prefix the underlying attribute with an underscore, that documents the intended "internal use only" aspect of the attribute; the read only unprefixed property is the only public interface. – ShadowRanger Mar 07 '18 at 02:06
0

Setters and getters are really useful when you want to perform some operations when setting or getting a value, such as verifying that the value is valid, or logging the access, or modifying another value.

For example, if you have a Screen class and want to keep an aspect ratio of 16:9, you would write:

class Screen:
    def __init__(self):
       self._height = 1080
       self._width = 1920

    @property
    def height(self):
       return self._height
    @name.setter
    def height(self,new):
        self._height = new
        self._width = 16*self._height/9

    @property
    def width(self):
       return self._width
    @name.setter
    def width(self,new):
        self._width = new
        self._height = 9*self._width/16
nyr1o
  • 966
  • 1
  • 9
  • 23