1

I know about properties in python and how they make it possible to use a classes attribute just like before but with some possible modification in between.

Anyway, having done some perl recently I came to love the idea of having even less code and having getter and setter combined

like:

sub filename {
   my $self      = shift;
   my $filename  = shift;
   if ($filename){ $self->$filename = $filename;}
   else {return $self->$filename;}
}

Obviously in perl you can omit the () behind the method which makes this approach "cleaner" and more transparent to the users of my class.

In py I could do similar the only downside being the need for () when accessing:

def filename(self, setter=None):
    if setter is not None:
         self._filename = setter
    else:
         return self._filename

To me this is just way more compact then doing the property thing and I believe my code is more readable.

So is there anything wrong with my approach or is it unidiomatic for some reason?

Thanks!

AlessandroEmm
  • 698
  • 7
  • 23

1 Answers1

3

The first problem is that the interface is different, and arguably less clear. unit.position = new_pos is turned into unit.position(new_pos). This is an accepted spelling for a mutation in some languages, but not so much in Python. Hardly anyone does that: even if property is not used, there are usually separate get and set methods. In other words, your code will stand out as non-idiomatic and confusing.

A consequence is that augmented assignment operators don't work any more: unit.position += velocity is not possible (it works if .position is a property). Another potential problem is that this doesn't support setting the property to None. You have to invent your own sentinel value (NO_VALUE = object() etc.), making the whole ordeal more ugly.

The supposed benefit on the implementation side is quite small: while you save an empty line or two, you need additional indentation and conditions. Note that properties do more than just setting or returning (otherwise it shouldn't be a property). Properties (8 lines)

@property
def width(self, new_width):
    self._width = new_width
    self._dirty = True

@width.setter
def width(self):
    return self._width

versus getter-setter-method (6 lines):

def width(self, new_width=None):
    if new_width is not None:
        self._width = new_width
        self._dirty = True
    else:
        return self._width

You save one blank line and one non-blank line, but for that you pay with

  • a worse interface
  • more indentation
  • more potential for errors (e.g. typo in condition, forgetting else)
  • delnan, I get your point and you are somewhat right. I see the Problem with the identation. I just personally think that having more methods = more line = more bloat and less concise. And when you have a class with like 10 properties I just gets harder to keep overview. But maybe this is just me. :-) Thanks for your opinion! – AlessandroEmm May 25 '13 at 11:53
  • @delnan 's opinion is also mine (+1). The parts of python fit together in many cool ways. If you invent your own "parts" or idioms, you lose future functionality (e.g. sorting iterating or incrementing properties) – Phil Cooper May 25 '13 at 12:39
  • @PhilCooper You're right, and I'm well aware that I'd go an unidiomatic way, I was just wondering what people do think about these approaches. Apart from beeing not idiomatic there isnt much complaint about the perl/scala way as far as I can see. – AlessandroEmm May 25 '13 at 16:45
  • @Alessandro See my second paragraph for two downsides, though they do not apply to all cases. And the rest of the post is challenging your claim that it's less code and more readable. –  May 25 '13 at 17:04