7
class Employee:

    def __init__(self, name):
        self.name = name

    def getName(self):
        return self.name

    @property
    def getNameAgain(self):
        return self.name


person = Employee("John")
print(person.getName())  #John <--(calling method)
print(person.name)  #John <--(using @property)

So I get the same results from using the getName(), so why do we use the @property decorator in getNameAgain() for? May I know what is better/advisable to use? Thank you in advance!

Shee
  • 123
  • 1
  • 6
  • 2
    Why use a get method when you can use a property? By the way, your `print(person.name)` is not using a property. It's just accessing the attribute directly. – khelwood Sep 30 '20 at 23:46
  • Note, it's important to understand, if all your getter/setter does is *nothing* then you *would just use a regular attribute*, i.e. `self.name = name` and then use `my_instance.name` directly. If, *later* you want to change the behavior of getting/setting, then you can *have encapsulation without the boilerplate of writing getters and setters*. In other words, the key point is that in your example, in Python, *you wouldn't use either* – juanpa.arrivillaga Oct 01 '20 at 00:11

1 Answers1

11

The key difference is in how the access is perceived by users of the property or method.

They certainly look different:

class Foo:
    def __init__(self, name):
        self._name = name

    def get_name(self):
        return self._name

    @property
    def name(self):
        return self._name


f = Foo('bar')
print(f.name)
print(f.get_name())

A method is called with parameters (or empty parentheses if it has none), a property is not.

Also, with a property there can be the expectation of being able to assign values to it, whereas with methods, you'd be looking for a separate setter:

    @name.setter
    def name(self, value):
        self._name = value

    def set_name(self, value):
        self._name = value


f.name = 'baz'
f.set_name('baz')

Again, with the property the syntax is unambiguous, with the setter, you might wonder about additional parameters.

Besides, if you only need a property, why use separate setters and getters and type more parentheses? After all, this is Python, not Java.

So when would you use a separate setter and getter method and not a property? If those aspects are what you want. I.e. you need additional modifiers when setting the value, or when retrieving the value, e.g. encoding.

By the way: I renamed your methods and property to be more in line with standard Python naming conventions. Since the main reason to use properties to begin with is aligning with user expectations (users of your library functions, not the software of course), it makes sense to do the same when naming stuff. So, get_name instead of getName and ._name for the hidden value instead of .name which signals that users are OK to just manipulate the value directly (which is fine, if that's expected).

Grismar
  • 27,561
  • 4
  • 31
  • 54