Manav Garg
Manav Garg

Manav Garg

@property in Python.

@property in Python.

Subscribe to my newsletter and never miss my upcoming articles

@property is a popular keyword in python. In this post you'll learn how can we use it to write more pythonic code and refactor any non pythonic code we had.


Let's consider an hypothetical number class which only allows numbers that are greater than 23 and less than 5. A typical OOPs program for it would look like this:

#python3.8
class HypotheticalNumber():

    def __init__(self, num=0):
        self.set_num(num) 

    def get_num(self):
        return self.num # notice public scope

    def set_num(self, num):
        if(num > 23 or num < 5):
            self.num = num
        else:
            self.num = 0

some_number = HypotheticalNumber(4)
print(some_number.get_num()) #4
print(some_number.num) #4
some_number.set_num(5) # sets to 0
some_number.num = 5 # sets to 5

As we can see, the above implementation has some major holes in it. Not only we're able to access our hypothetical number by simply referring to some_number.num directly, we can also change it by direct access and break the core rule that our class is based upon, i.e. assigning a value equal to 5.


There's a pythonic way to do it.

@property is a decorator that handles getting, setting and deleting of class variables, the way it was meant to be in Python. A pythonic program for the above scenario would look like:

class HypotheticalNumber():

    def __init__(self, num=0):
        self.num = num

    @property
    def num(self):
        return self.__num

    @num.setter
    def num(self, num):
        if(num > 23 or num < 5):
            self.__num = num
        else:
            self.__num = 0

    @num.deleter
    def num(self):
        del self.__num

some_number = HypotheticalNumber(4)
print(some_number.num) #4
some_number.num = 5 # sets to 0

Let's take it step by step.

  1. @property is used to create a getter like function which has the same name as the class variable itself.
  2. @num.setter is used to create a setter like function which defines what to do while setting the variable.
  3. @num.deleter is used to create a deleter like function which defines what to do while deleting the varible.
  4. Notice that all the functions have same name. It is necessary for the program to work.

What if my project contains code with getter and setter methods instead of property?

Well, you can always rewrite the code, or, there's another way to refactor it. It might save some time for you. Instead of adding @property as a decorator, we can just add the getter and setter methods to the property function.

#python3.8
class HypotheticalNumber():

    def __init__(self, num=0):
        self.set_num(num) 

    def get_num(self):
        return self.__num # notice dunder

    def set_num(self, num):
        if(num > 23 or num < 5):
            self.__num = num
        else:
            self.__num = 0

    num = property(get_num, set_num)

some_number = HypotheticalNumber(4)
print(some_number.get_num()) #4
print(some_number.num) #4
some_number.set_num(5) # sets to 0
some_number.num = 5 # sets to 0

As you can see, we just needed to change the variables and add a special line num = property(get_num, set_num) that secured the holes we had in our initial code and saved us a lot of time!

 
Share this