Why using getters/setters in python

Question:

I stumbled across the below example of using getters and setters in a different question
Preferred way of defining properties in Python: property decorator or lambda?

Since python has implicit getters and setters, I wonder what the reason is to define them explicitly as below. Is there any advantage in those examples or does it only make sense when the getters/setters involve anything more complicated than the simplified examples below?

class Bla(object):
    def sneaky():
        def fget(self):
            return self._sneaky
         def fset(self, value):
            self._sneaky = value
        return locals()
    sneaky = property(**sneaky())

Recent versions of python enhanced the decorator approach:

class Bla(object):
    @property
    def elegant(self):
        return self._elegant

    @elegant.setter
    def elegant(self, value):
         self._elegant = value
Asked By: chrise

||

Answers:

Normally you should just use attribute access. getters and setters are pointless if they are doing nothing more than adding overhead

The nice thing about the way Python ties getters and setters to properties, is that you can easily change an attribute into a property without having to go and refactor all the code that uses the class.

Answered By: John La Rooy

You’ve already answered your own question as to the differences in syntax. Your second snippet wasn’t possible in prior versions, hence the first example.

In Python, there isn’t much value-add to define a property in this matter for a vanilla get/set combo (it’s more of a concern in compiled languages, such as C#, where changing from a field to a property would necessitate a recompilation of all client code, whereas the change to the implementation of a property in C# wouldn’t necessarily require a recompilation). Typically, one or both of the methods would usually contain some logic (validation, lazy initialization perhaps).

Sometimes you might want to make a property read-only, so you could do:

@property
def foo(self):
    return self.__foo

While not strictly read-only, it would require you to handle the python name-mangling yourself.

Answered By: Nathan Ernst

For instance, I want to segment a sentence whenever I update the variable or assign a sentence to that variable.

Without a setter I should do the segmentation everywhere I update or assign, and it’s error-prone. And the __post_init__ of dataclass only can help me do that when I initiate the variable.

Then I can use the setter as follows:

import seg_tool from somewhere

class Bla(object):
    self.sentence_seg = []
    self.sentence = '' 

    @property
    def sentence(self):
        return self._sentence

    @sentence.setter
    def sentence(self, value):
         self._sentence = value 
         self.sentence_seg = seg_tool.cut(value)

In short, it provides me an event which let me know when a update or assign happened and I can do whatever I want to do using the event.

Answered By: Lerner Zhang
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.