Is it worth using Python's @property decorator if you don't mind using a method to access a property?

Viewed 972

Update:
Thanks for the responses. I think it finally helped make things click in my head now.

Python prescribes this workflow:

  1. start by just using properties and avoid over-engineering with boilerplate getter/setter
  2. when more logic is necessary, switch over to getter/setter using the @property decorator to maintain a consistent API to reduce refactoring

As oppose to these workflows:

  1. start out using getter/setter to avoid refactoring later.
    • this adds unnecessary boilerplate code that might never be needed

or

  1. start out using properties
  2. switch to non-@property getter/setter when more logic is necessary
  3. refactor all dependent code to use getter/setter instead of properties

Thanks again for helping me understand these timeline of events and the awesome usefulness of @property.

If either of you want to add an answer, I'll accept it to close this out. Thanks again

Original:

I've been reading up on Python's @property decorator.

I understand that it is useful to allow library users to get properties like class.property while allowing library maintainers to refactor the getter logic behind the property-like interface much like a getter method.

What I don't understand is, why go through the hassle of using decorators to achieve an interface that resembles a property, like class.property. What is wrong with have a normal method like interface, like class.property()?

Is there something I'm missing? I don't understand why the extra parenthesis in the method call is problematic enough to warrant using a decorator?

Maybe the following code can help explain what I'm trying to get at better?:

class Class:
    def __init__(self, value):
        self._value = value

    def value(self):
        return self._value

print(Class('calling method').value())

class Class:
    def __init__(self, value):
        self._value = value

    @property
    def value(self):
        return self._value

print(Class('accessing property').value)

Is it because it makes setters prettier? So instead of:
klass.set_value('some value')
you can have?:
klass.value = 'some value'

Like this example code?:

class Class:
    def __init__(self, value):
        self._value = value

    def value(self):
        return self._value

    def set_value(self, value):
        self._value = value

klass = Class('calling method')
klass.set_value('calling method2')
print(klass.value())

class Class:
    def __init__(self, value):
        self._value = value

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        self._value = value

klass = Class('accessing property')
klass.value = 'accessing property2'
print(klass.value)

Are the reasons to use the @property decorator purely to make the class interface more aesthetically pleasing?

I do think the interface ends up looking nicer, but I'm wondering if I'm missing something more.

Thank you for your time :)

1 Answers

I'll just post an answer to close out this thread, since the commenters seem like they are busy:

Python prescribes this workflow:

  1. start by just using properties and avoid over-engineering with boilerplate getter/setter
  2. when more logic is necessary, switch over to getter/setter using the @property decorator to maintain a consistent API to reduce refactoring

As oppose to these workflows:

  1. start out using getter/setter to avoid refactoring later.
    • this adds unnecessary boilerplate code that might never be needed

or

  1. start out using properties
  2. switch to non-@property getter/setter when more logic is necessary
  3. refactor all dependent code to use getter/setter instead of properties

I hope this helps others better understand the reason Python prescribes the use of @property.

Related