2

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
Community
  • 1
  • 1
chrise
  • 4,039
  • 3
  • 39
  • 74
  • "Since python has implicit getters and setters". Can you expand on this? Are you saying that if you don't use `property` python will make `sneaky` an attribute anyway? If so, that's not true. – SethMMorton Jan 31 '14 at 02:28
  • Normally, the only reason someone would put a getter or setter is to do other stuff in the background(such as set a flag or check the input) when an attribute is modified. – kirbyfan64sos Jan 31 '14 at 02:51

3 Answers3

3

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.

John La Rooy
  • 295,403
  • 53
  • 369
  • 502
1

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.

Nathan Ernst
  • 4,540
  • 25
  • 38
0

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.

Lerner Zhang
  • 6,184
  • 2
  • 49
  • 66