4

I'm switching from Java to Python and am having trouble understanding the @Property decorator. I realized in OOP languages (such as Java) I don't fully understand the point of mutator methods in the following sense:

Say we have a private variable x. So we need to make a mutator method

public void setX(int val) {
  x = val;
}

Now if x had been public then we could have just did x = val and it would have been easier and there would have been no difference. Now in a more complicated scenario, we could add restrictions, perhaps it doesn't make sense for x to be less than 10

public void setX(int val) {
  if(x < 10)
    x = 10;
  else
    x = val;
}

So in a sense is the point of having mutator methods to impose restrictions on the data? So it's to achieve encapsulation? I'm thinking of this because with Python's @Property (correct me if I'm wrong) you're not calling a mutator method but in effect it works the same way in the sense additional logic can happen before the value is changed.

A corolary question is, if we do have such a simple mutator method as in the first example, should the variable just be made public?

7

To answer your last question first - in Java you should always use accessor and mutator methods, because if you make a public field and later decide it needs extra logic - you're gonna have a bad time. If you are lucky and your code is not a library "all" it'll take is cleaning the build product, rebuilding, and going through countless places where you access that variable, changing them by hand. If you are a library - though luck. You're gonna break your users code...

In Python - it doesn't matter. Attribute syntax(and AFAIK implementation) is the same for fields and properties. The only difference is whether your custom method will be called or the default __getattribute__/__setattribute__ which will look inside the __dict__(or set a value in it). So if you don't need the extra logic - just use a regular field. You can always change it later.

As for the "why" - the most common reason for using a @property in Python is that you don't store the actual , direct value inside the object.

For example:

class Vector2D(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @property
    def length(self):
        return (self.x ** 2 + self.y ** 2) ** 0.5

    @length.setter
    def length(self, value):
        multiplier = value / self.length
        self.x *= multiplier
        self.y *= multiplier

We don't store the length directly - we only store x and y. But we can still get and set the length like it was an ordinary property - and our @property code does the work behind the scenes for us.

  • If you are lucky and your code is not a library "all" it'll take is cleaning the build product, rebuilding, and going through countless places where you access that variable, changing them by hand. .... Or put the cursor in the field declaration, alt+shift+r, select "encapsulate field" from the menu, then press enter s couple of times. (This is for eclipse... Other ides may have different sequences) – Jules Apr 18 '17 at 21:21
2

As stated here:

https://stackoverflow.com/questions/14594120/python-read-only-property

I've also seen the @property decorator used to signify that a field is "read-only". For example:

class Thing(object):
    def __init__(self, path):
        self._path = path

    @property
    def path(self):
        return self._path

Of course, we're all consenting adults in Python and this isn't actually read-only, but you won't be able to assign through the path property, only through the _path field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.