Understanding the @Property decorator in Python
|In this Python article, we will discuss the use and working of the property function along with its implementations and examples. Let’s get started.
1. What is the Use of Property in Python?
To make quick and simple use of Object-Oriented Programming, we use the getter and setters method. These setters and getters are present in a built-in decorator termed as
@property
.
The foremost aim of using Property()
function is to develop a class’s property.
Before going into details on what @property
decorator is, let us first understand why it would be needed in the first place.
Syntax: property(fget, fset, fdel, doc)
Provided Parameters:
- fget() – This gets the attribute value.
- fset() – This sets the attribute value.
- fdel() – This delete the attribute value
- doc() – This holds the attribute documentation in string data type.
The function returns one property attribute from the provided data of getter, setter, and deleter.
NOTE: When the property function is used with no argument then it will return a base property attribute with no getter, setter or deleter. Also, if we call the property function without providing doc, then the getter function’s doc-string is used by the property function.
2. How to use Class without Getters and Setters?
Suppose, we have created a Python class that is used to calculate the total simple interest and also have a function that can convert the simple interest into principal amount.
Let’s implement this example without using any setter and getter methods.
class SimpleInterest: def __init__(self, simple_interest): self.simple_interest = simple_interest def find_principle(self, t=1, r=5): return (self.simple_interest * 100)/5*1 value = SimpleInterest(4000) print("The simple interest is: ", value.simple_interest) print("The principle amount is: ", value.find_principle())
Output The simple interest is: 4000 The principle amount is: 80000.0
In the above example, we can see that due to floating division, there is an extra decimal place and it is considered as the floating-point arithmetic error.
When an object attribute is retrieved or is updated, then the object’s built-in __dict__
dictionary value is searched. Considering the previous example
print(value.__dict__)
Output {'simple_interest': 4000}
Therefore we can access and updated the value of simple_interest easily using the object reference and there is no check on the way it is updated.
value = SimpleInterest(4000) value.simple_interest = 100 print("The simple interest is: ", value.simple_interest) print("The simple interest is: ", value.__dict__['simple_interest'])
Output The simple interest is: 100 The simple interest is: 100
Internally, value.simple_interest
is also translated as value.dict['simple_interest']
which is also evident from the last program output.
3. Using Getters and Setters
Let’s consider an example where we have the temperature provided in a class TempCelcius
and we need to extend the use of the class.
According to thermodynamics, any object can have the lowest temperature to -273.15 Celsius (Known as Absolute Zero).
We need to keep this constraint, a quick solution is to define the getter and setter method for changing the value of the temperature attribute of the class and keep the __temperature
as a class private variable.
Let’s implement the example to understand this value limitation better.
class TempCelsius: def __init__(self, temp=0): self.setter_temp(temp) # getter method def getter_temp(self): return self.__temperature # setter method def setter_temp(self, giventemp): if giventemp < -273.15: raise ValueError("Temperature below -273.15 is not possible.") self.__temperature = giventemp # Create a new object valuerecorded = TempCelsius(-370) print(valuerecorded.getter_temp())
Output Traceback (most recent call last): File "main.py", line 16, in valuerecorded = TempCelsius(-370) File "main.py", line 3, in init self.setter_temp(temp) File "main.py", line 12, in setter_temp raise ValueError("Temperature below -273.15 is not possible.") ValueError: Temperature below -273.15 is not possible.
We have clearly implemented the restriction.
But, there is still a big problem when changes have to be done, if it is a legacy code written without setters and getters, then, changing each line and function can make a great deal of problem which can even take time to change more than thousands of lines.
To overcome such an update and to keep it compatible backward, we use a quick solution, which is the use of @property
decorator.
To understand this better we should learn about the Decorators in Python.
class TempCelsius: def __init__(self, temp=0): self.setter_temp(temp) # getter method def getter_temp(self): print("Getting the temperature value...") return self._temperature # setter method def setter_temp(self, giventemp): print("Getting the temperature value...") if giventemp < -273.15: raise ValueError("Temperature below -273.15 is not possible.") self.__temperature = giventemp proper_temp = property(getter_temp, setter_temp) # Create a new object valuerecorded = TempCelsius(-370) print(valuerecorded.proper_temp())
4. How to use class with property function?
We can also use the property function along with a class. Let’s check how it works.
Note: With this implementation, we will access, update and delete the data like we normally do but not it is done in a controlled way. The methods that we implement are responsible for doing all the operations.
class Words: def __init__(self, string): self.__text = string def getstring(self): print('Fetching Line(getter): ', end="") return self.__text def setstring(self, string): print('Setting value to: ' + string) self.__text = string def delstring(self): print('Deleting value') del self.__text print("Successfully deleted the string") value = property(getstring, setstring, delstring) # Main line = Words('The day and the night makes one cycle') print(line.value) line.value = 'The world' print(line.value) del line.value print(line.value)
Output Fetching Line(getter): The day and the night makes one cycle Setting value to: The world Fetching Line(getter): The world Deleting value Successfully deleted the string Fetching Line(getter): Traceback (most recent call last): File "/Users/test/IdeaProjects/personal/codingeek/Python/./test.py", line 27, in print(line.value) File "/Users/test/IdeaProjects/personal/codingeek/Python/./test.py", line 7, in getstring return self.__text AttributeError: 'Words' object has no attribute '_Words__text'
5. Using @property decorator
Using the @property
decorator works similarly to the property()
function.
class Words: def __init__(self, string): self.__text = string @property def value(self): print('Fetching Line(getter): ', end="") return self.__text @value.setter def value(self, string): print('Setting value to: ' + string) self.__text = string @value.deleter def value(self): print('Deleting value') del self.__text print("Successfully deleted the string") # Main line = Words('The day and the night makes one cycle') print(line.value) line.value = 'The world' print(line.value) del line.value print(line.value)
Output (Same as previoous program) Fetching Line(getter): The day and the night makes one cycle Setting value to: The world Fetching Line(getter): The world Deleting value Successfully deleted the string Fetching Line(getter): Traceback (most recent call last): File "/Users/test/IdeaProjects/personal/codingeek/Python/./test.py", line 27, in print(line.value) File "/Users/test/IdeaProjects/personal/codingeek/Python/./test.py", line 7, in getstring return self.__text AttributeError: 'Words' object has no attribute '_Words__text'
6. Conclusion
Finally, if we sum up, in this article we learned about property decorator in python along with why we use property and how can we use property in python. We have also covered:
- What is the use of property in Python?
- How to use class without getters and setters?
- Using Getters and Setters in python
- How to use class with property function?
- How to use the @property decorator in python?
Helpful Links
Please follow the Python tutorial series or the menu in the sidebar for the complete tutorial series.
Also for examples in Python and practice please refer to Python Examples.
Complete code samples are present on Github project.
Recommended Books
An investment in knowledge always pays the best interest. I hope you like the tutorial. Do come back for more because learning paves way for a better understanding
Do not forget to share and Subscribe.
Happy coding!! ?