The property decorator is a great way to "protect" attributes one wants to set once and never change again. I usually deal with this this way (btw., following a the advice here):
self._name = 'foo'
@property
def name(self):
return self._name
so trying to set name directly yields an AttributeError.
However, I often see the following pattern:
@name.setter
def name(self, value):
self._name = value
@property
def name(self):
return self._name
which seems a little counter-intuitive, as it enables exactly what I want to avoid, and requires extra coding, i.e, theoretically
self.name = 'bar'
would suffice, although it is clear that this would be the worst way to deal with the problem.
The best explanation I can come up with is something like a message from the author saying "you should not change this attribute but if you really want to, there is a mechanism to do it without changing a 'protected' attribute". But then, python doesn't really protect attributes.
So, what's the point, which is more pythonic and why?
You're correct that there's no good reason to use a property if you're not doing anything special in the getter or setter. However, if you do want to do something special (like validate new values, or normalize them in some way), then it makes a lot of sense.
For example, this class's foo attribute will always be clamped between 0 and 1 (and non-numerical values will cause an error immediately):
class Foo:
_foo = 1.0
@foo
def probability(self):
return self._foo
@foo.setter
def foo(self, value):
if value < 0:
value = 0
elif value > 1:
value = 1
self._foo = value
An example with a trivial setter, but a complicated getter might be something like this (deferring an expensive initialization that might not be needed):
class Foo:
_foo = None
def initialize_foo(self):
self._foo = some_expensive_calculation()
@property
def foo(self):
if self._foo is None:
self.initialize_foo() # need the default value
return self._foo
@foo.setter
def foo(self, value):
self._foo = value
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With