Reputation: 1027
From one of the blogs, I have the following code, which I am using to understand the working of python property
.
class Celsius:
def __init__(self, temperature = 0):
self._temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
@property
def temperature(self):
print("Getting value")
return self._temperature
@temperature.setter
def temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self._temperature = value
Q1: Under the __init__
method, why is the author using self._temperature
. Should it not be self.temperature
? How will the control go to @temperature.setter
?
Upvotes: 3
Views: 68
Reputation: 76578
Whether it is correct to use self._temperature
in __init__()
is sometimes a matter of taste. In essence there is now a third method (apart from the setter
and getter
) that knows about the attribute the actual value is stored. IMO that is not nice, and could lead to errors if you refactor the class and change the attribute, but it is not incorrect per se.
There can be situations that the setter already assumes a value is stored in some other way. Not here, but e.g. when the self._temperature
should only be set if it were increased. In that case you have to directly access the attribute. (This situation can be circumvented by testing for the "storage" attributes existence using hasattr(self, "_temperature")
within the setter and getter and initialising appropriately).
There is never a point where the control goes to the setter. The setter gets used if you do:
self.temperature = some_value
you can always directly set the "hidden" attribute (in this case self._temperate
) from any of the other methods (or directly accessing the attribute on an instance of Celsius
). Please note that this just happens to be the property name with an underscore before it, it could be any (free) name.
Upvotes: 3