A decorator is a function that takes another function as its argument and extends its functionality without changing its source code. In this tutorial, we are going to discuss some important built-in Python decorators such as @property, @classmethod, and @staticmethod. If you do not have basic knowledge of decorators, first study them here.
So, without further ado, let’s get started.
The @property decorator
The @property decorator is a built-in Python decorator that is used for the property() function. Let’s take an example of a Student class to understand how and why to use this decorator.
Let’s say we have a Student class having properties, first name, last name, and score. This class also contains a method that returns the full name of the student. Let’s see.
class Student:
def __init__(self, first, last, score):
self.first = first
self.last = last
self.score = score
def full_name(self):
return self.first + " " + self.last
std = Student("ashton", "agar", 98)
std.full_name()
Output
ashton agar
Now, let’s say we want to add a feature in which the user can directly change their full name, and when they change it, their first name and last name get updated as well.
One way of doing this is to create a different method, which updates the value of first and last names. Since we are creating a new setter method and for readability purpose, we change the name of full_name()
to get_full_name()
to have consistency in the code, i.e.,
class Student:
def __init__(self, first, last, score):
self.first = first
self.last = last
self.score = score
def get_full_name(self):
return self.first + " " + self.last
def set_full_name(self, fullname):
first, last = fullname.split(" ")
self.first = first
self.last = last
std = Student("ashton", "agar", 98)
std.set_full_name("ashton turner")
std.get_full_name()
Output
ashton turner
Each time we want to change the full name or retrieve it, we need to use different methods. Instead of doing this, we can use the property()
method to implicitly call the setters, getters, and deleters. It returns an object of the property class. Let’s see.
class Student:
def __init__(self, first, last, score):
self.first = first
self.last = last
self.score = score
def get_full_name(self):
return self.first + " " + self.last
def set_full_name(self, fullname):
first, last = fullname.split(" ")
self.first = first
self.last = last
full_name = property(get_full_name, set_full_name)
std = Student("ashton", "agar", 98)
std.full_name = "ashton turner"
print(std.full_name)
Output
ashton turner
Instead of using the property()
method, a better way is to use the @property
decorator. It is more readable and convenient to use. Let’s see.
class Student:
def __init__(self, first, last, score):
self.first = first
self.last = last
self.score = score
@property
def full_name(self):
return self.first + " " +self.last
@full_name.setter
def full_name(self, fullname):
first, last = fullname.split(" ")
self.first = first;
self.last = last
@full_name.deleter
def full_name(self):
del self.first
del self.last
std = Student("ashton", "agar", 98)
print(std.full_name)
std.full_name = "ashton turner"
print(std.full_name)
print(std.first, std.last)
Output
ashton agar
ashton turner
ashton turner
The @property
decorator allows us to use full_name
as a property now. Therefore, we can retrieve it without the parenthesis.
The @full_name.setter
indicates that it is a setter method for the full_name
property. Using this, you can update the value like you would for any property.
We can also delete the property of that instant using @full_name.deleter. Let’s see.
del std.full_name
print(std.full_name)
Output

In the deleter method, we delete the first and last names. Therefore, when we try to call the full name after deleting it, we get an error.
The @classmethod decorator
A regular method in a class, or more specifically an instance method, is a method that is bound to the object instance. It takes an implicit parameter self, which points to the object instance that invoked it. A class method, however, is bound to the class. It takes an implicit pointer to its class as its parameter. By convention, we denote it by cls
. To create a class method, use the @classmethod
decorator. Class methods are often used as alternative constructors or as factory methods.
The @staticmethod decorator
The static method, on the other hand, does not take an object instance or a class, which means that it can’t access their states. It is also bound to its class. The @staticmethod
decorator creates a static method. They are used to make helper or utility functions. These methods have a logical connection with the class but do not use class or object state.
Example of @classmethod and @staticmethod
Let’s take an example to understand both. We create a Student class, which contains properties: first name and last name. However, a user can directly instantiate an object using the full name as well. We will implement it by using the class method as an alternative constructor. Moreover, we have a static method scholarship()
that takes a GPA and tells whether a student is eligible for a scholarship or not. This method does not use either class or object state but has a logical connection with the class.
class Student:
def __init__(self, first, last):
self.first = first
self.last = last
def display_info(self):
print(f"The name of the student is {self.first} {self.last}")
@classmethod
def from_string(cls, fullname):
first, last = fullname.split(" ")
return cls(first, last)
@staticmethod
def scholarship(gpa):
if gpa >= 3.8 and gpa <= 4.0:
print("eligible for scholarship")
else:
print("Not eligible")
# using the default constructor to create a Student instance
std1 = Student("Ashton", "Agar")
std1.display_info()
# using the alternatice constructor to create a Student instance
std2 = Student.from_string("Karen Hill")
std2.display_info()
# using the static method
Student.scholarship(3.9)
Student.scholarship(3.4)
Output
The name of the student is Ashton Agar
The name of the student is Karen Hill
eligible for scholarship
Not eligible
You can invoke the class method and static method with either the object instance or the class itself.