DEV Community

loading...
Cover image for @property in Python.

@property in Python.

sigmapie8 profile image Manav ・2 min read

@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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!

Discussion (0)

pic
Editor guide