I know that it looks prettier when the getter is simple:
class User:
first_name: str
last_name: str
def full_name_1(self):
return f"{self.first_name} + {self.last_name}"
@property.getter
def full_name_2(self):
return f"{self.first_name} + {self.last_name}"
User.full_name_1
User.full_name_2()
but the bigger impact is obscuring the fact that you are making a function call.
The real power of @property is not the getter, but the setter.
You can define a custom setter with validation logic OR You can intentionally leave out a setter so that an attribute is read only:
class X:
_name = 5
@property.getter
def name():
return self._name
If you are not doing either of these things, property is just hiding a function call which may contain side effect, which is a practice I consider dangerous. I have seen network calls hidden get behind @property. Never do this.