Python Class Properties
Properties are setter/getter methods that set/get the value of a variable contained in the class.
class Mass(): def __init__(self, kilograms): self._kilograms = kilograms # This is the "getter" method for the property "kilograms" @property def kilograms(self): return self._kilograms; # The setter for "kilograms". Here, we guard against assigning a negative value # before storing it in the backing variable _kilograms @kilograms.setter def kilograms(self, massInKilograms): if (massInKilograms < 0): raise Exception("Mass cannot be negative.") self._kilograms = massInKilograms aBall = Mass(25) print('Mass in kilograms', aBall.kilograms) aBall.kilograms = 100 print('Mass in kilograms', aBall.kilograms) # Oops, the mass of something cannot be negative. aBall.kilograms = -1
Output
Mass in kilograms 25 Mass in kilograms 100 Traceback (most recent call last): File "examples.py", line 25, in <module> aBall.kilograms = -1 File "examples.py", line 25, in kilograms raise Exception("Mass cannot be negative.") Exception: Mass cannot be negative.
Properties are defined as functions but used as instance variables. They are often used to do other things in addition to just getting and setting a value. A good example of a property getter is to guard against bad data, or data that is outside of some bounds, or to pre-process data, such as converting the value of a variable to a different unit of measure.
Using properties requires using the special decorators @property and @[name].setter where [name] is the property name exposed as a variable.
Let's extend the example above to allow the intenal value of "mass" to be expressed, and set, in units of grams or kilograms. This demonstrates how a backing variable can be used for two or more properties
class Mass(): def __init__(self, kilograms): self._kilograms = kilograms # The getter for the property "grams" @property def grams(self): return self._kilograms * 1000.0 # The getter for the property "kilograms" @property def kilograms(self): return self._kilograms; # The setter for grams. @grams.setter def grams(self, massInGrams): if (massInGrams < 0): raise Exception("Mass cannot be negative.") self._kilograms = massInGrams / 1000.0 # The setter for kilograms. @kilograms.setter def kilograms(self, massInKilograms): if (massInKilograms < 0): raise Exception("Mass cannot be negative.") self._kilograms = massInKilograms aBall = Mass(25) print('Mass in kilograms', aBall.kilograms) # outputs 25 print('Mass in grams', aBall.grams) # outputs 25000