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!! ?

Recommended -

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
Index