Using @Property Versus Getters and Setters

Using @property versus getters and setters

Prefer properties. It's what they're there for.

The reason is that all attributes are public in Python. Starting names with an underscore or two is just a warning that the given attribute is an implementation detail that may not stay the same in future versions of the code. It doesn't prevent you from actually getting or setting that attribute. Therefore, standard attribute access is the normal, Pythonic way of, well, accessing attributes.

The advantage of properties is that they are syntactically identical to attribute access, so you can change from one to another without any changes to client code. You could even have one version of a class that uses properties (say, for code-by-contract or debugging) and one that doesn't for production, without changing the code that uses it. At the same time, you don't have to write getters and setters for everything just in case you might need to better control access later.

when to use getter and setter with property?

You should generally prefer to use "protected" variables (such as those starting with _) with properties (not separate functions that users need to call, that's just clunky), as it confers some advantages. This encapsulation is very handy as it:

  • lets you control the internal data completely, such as preventing people entering ages like -42 (which they will do if they can); and
  • lets you change the underlying implementation in any manner you want, without affecting clients.

For example on that last point, you may want to maintain a separate structure of all names and simply store references to those names in your Person class. This can allow you to store many more names, as the surname "Von Grimmelshausen" would be stored once (in the separate structure) and as much smaller indexes in all the Person objects that use it.

You can then totally change the naive getter from:

@property
def surname(self):
return self._surname

to:

@property
def surname(self):
return self._surname_db[self._surname_index]

without any changes to clients.

Properties vs. Getters and Setters

The fact that you perform checks in the __init__ method does not guarantee that the value cannot be altered later to an invalid value.

For example:

x = OurClass(10)
x.OurAtt = -20

We thus want to run the test every time the ourAtt value is set. We can do this with:

class OurClass:

def __init__(self, a):
self.OurAtt = a

@property
def OurAtt(self):
return self._OurAtt

@OurAtt.setter
def OurAtt(self,a):
if a < 0:
self._OurAtt = 0
elif a > 1000:
self._OurAtt = 1000
else:
self._OurAtt = a

Furthermore it allows to make the code more readable: every setter checks whether one specific value is valid. This is usually a better approach than checking all values in the same method, since if we alter the specifications of one value, we only have to modify the corresponding setter.

Another advantage is that validation is done in a transparent matter: you do not have to change an attribute into a "setter method": for the user, it just looks like he/she alters an attribute. You can thus later in the process - when users already make use of the attribute - decide to add some validation without changing the interface.

Finally it is more declarative and thus usually more "Pythonic".

Getters, setters, and properties best practices. Java vs. C#

Pre-C# 6

I'd use the last of these, for a trivial property. Note that I'd call this a public property as both the getters and setters are public.

Immutability is a bit of a pain with automatically implemented properties - you can't write an auto-property which only has a getter; the closest you can come is:

public string Foo { get; private set; }

which isn't really immutable... just immutable outside your class. So you may wish to use a real read-only property instead:

private readonly string foo;
public string Foo { get { return foo; } }

You definitely don't want to write getName() and setName(). In some cases it makes sense to write Get/Set methods rather than using properties, particularly if they could be expensive and you wish to emphasize that. However, you'd want to follow the .NET naming convention of PascalCase for methods, and you wouldn't want a trivial property like this to be implemented with normal methods anyway - a property is much more idiomatic here.

C# 6

Hooray, we finally have proper read-only automatically implemented properties:

// This can only be assigned to within the constructor
public string Foo { get; }

Likewise for read-only properties which do need to do some work, you can use member-bodied properties:

public double Area => height * width;

Property-like methods instead of getters & setters in C++?

Yes and no.

Properties are syntactic sugar for hiding functions. So yes. You can write a function that returns a reference and get something that, on the surface, looks like a property.

But consider this: behind the property is a setter function that can (and should) do more than simply set a value. The point of any setter is to ensure that setting the value does not harm the state of the object.

By replacing the setter with a function that returns an unprotected reference to a private member you are stripping away this line of defense. The caller can use that reference as they see fit and to the possible detriment of the object. This might be just fine, depending on the nature of the member, but you might as well be honest. Declare the member public, improve readability, and save yourself the hassle of writing the function.

As for the const part of the question, you can sort of (and this is an ugly, simplistic sort of "sort of") think of int& age() as int& age(Person * this) and int age() const as int age(const person * this)

In OP's example, age() is never invoked on a constant Person, so there is no reason for int age() const to ever be invoked.

usage of property vs getters/setters in business classes

No. Getters and setters are only there in Java because it doesn't have properties. It makes for much cleaner code to use properties. And then if you need a getter or a setter, you can build it into the property, but you don't have to litter the accessing code with a bunch of function calls.

Getters and Setters versus class method

Getters and setters are just syntactic sugar. The compiler will compile your getters and setters into getter and setter methods eventually. So by writing getter and setter methods yourself, you are kind of doing the job of the compiler.

Therefore, I recommend you to use getters and setters, because one of their main purposes is to replace getter and setter methods.

Here are some other advantages of using getters and setters:

  • Getters and setters can save you a lot of time if you only need getters and setters without any logic:

    public int Property { get; set; }
  • In my opinion, the aesthetic of getters and setters look better. Compare:

    obj1.Property += obj2.Property;

    with

    obj1.SetProperty(obj1.GetProperty() + obj2.GetProperty());

    I feel like the latter just has too many parentheses.

  • Keep the setters and getters close to the property declaration. If you use getter and setter methods, you could accidentally write other methods between the property declaration and the getter/setter methods, causing the getter/setter methods to slowly "drift away" from the property declaration. Next time you want to find it, you need to scroll up and down. With getters and setters, they will always be below the property declaration.



Related Topics



Leave a reply



Submit