@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.
-
@property
is used to create a getter like function which has the same name as the class variable itself. -
@num.setter
is used to create a setter like function which defines what to do while setting the variable. -
@num.deleter
is used to create a deleter like function which defines what to do while deleting the varible. - 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!
Top comments (0)