In Python class, we can define three types of functions/methods- regular method(self), classmethod(cls), and staticmethod. Among these three methods, you will be using the regular methods for most of the cases because
classmethod
and
staticmethod
have their specific usages and are not often used in the
class
body.
Although this article is about the difference between Python class
classmethod
and
staticmethod
but for a quick reference, we will discuss the regular method first for a better understanding of
classmethod
and
staticmethod
.
Difference between Python classmethod and staticmethod
Python regular Method with
self
Methods are nothing but functions defined inside the
class
body, and to define a regular method in a
Python class
we pass a conventional
self
argument to every method. Where the self represents the instance of the class that calls that method.
For example
class Student:
def __init__(self, name):
self.name = name
def show_name(self):
return self.name
r = Student("Ravi")
print(r.show_name()) #Ravi
In this example the
r
is the one instance/object of class
Student()
, similarly, a class can have multiple instances. When the
r
call the class method
show_name(self)
using the
r.show_name()
statement, it does not require passing the
self
parameter, because it gets automatically filled by the interpreter, as the object which is calling the method.
In our case
r
is calling the
show_name(self)
method, so at the backend, the interpreter will treat the
r
instance as the self parameter and show the result accordingly. This is how a regular method work in Python class, in which an instance or object is automatically passed as the first parameter of the method as
self
.
Now let's see another example of the class regular method (self).
class Student4Grade:
fee = 2300
def __init__(self, fname, lname, age):
self.fname = fname
self.lname= lname
self.age = age
def fullname(self):
return self.fname + " "+ self.lname
def fee_increment(self):
self.fee += 200
def show_fee(self):
return f"{self.fname} fee is: {self.fee}"
rahul = Student4Grade("Rahul", "Singh", 10)
ravi = Student4Grade("Ravi", "kumar", 9)
print(ravi.fullname())
print(rahul.fullname())
rahul.fee_increment()
print(ravi.show_fee())
print(rahul.show_fee())
Output
Ravi kumar
Rahul Singh
Ravi fee is: 2300
Rahul fee is: 2500
Behind the code
In this example, we created two instances/objects of class
Student4Grade(
)
rahul
and
ravi
. And using the
rahul.fee_increment()
statement we increased the fee for
rahul
only, becaue when the
rahul.fee_increment()
statement gets executed, it passed only
rahul
instance to the
fee_increment(self)
method, not the
ravi
instance.
The fee structure should remain the same for all the similar grade students, but with the self or regular method, we can only change a constant thing for a specific object using a single statement. You can say we can also call the
fee_increment()
method using the
ravi
object it will increase the fee for
ravi
too, that's one of the cases.
This will do the trick but let's say if we have thousands of student objects, then it would not be a feasible solution. Some could also say to change the
fee
property using a class name outside the class and change it for every instance, this will also do the trick, but it violates the encapsulation and data hiding property of the class. To tackle such problems where we want to create a method that will access or change the class property for all the instances, there we can use the @calssmethod.
Python
@classmethod
with
cls
@classmethod
is a
Python decorator
. It is used to bind the specific class method to the class instead of an object, unlike regular class methods. In a regular method, we pass
self
as the first argument to the method, similarly in
@classmethod
we pass
cls
as the first argument to the method.
Like
self
the word
cls
is a conventional name. You can use any arbitrary name instead of
cls
, but it recommends following the convention and use
cls
. As
self
represent the object the
cls
represent the class itself.
Syntax
class class_name:
@classmethod
def method_name(cls):
.....
Now let's solve the problem that we been facing in the above example
class Student4Grade:
fee = 2300
def __init__(self, fname, lname, age):
self.fname = fname
self.lname= lname
self.age = age
def fullname(self):
return self.fname + " "+ self.lname
@classmethod
def fee_increment(cls): #cls is Student4Grade
cls.fee += 200 # equivalent to Student4Grade.fee
def show_fee(self):
return f"{self.fname} fee is: {self.fee}"
rahul = Student4Grade("Rahul", "Singh", 10)
ravi = Student4Grade("Ravi", "kumar", 9)
print(ravi.fullname())
print(rahul.fullname())
Student4Grade.fee_increment() #call fee_increment() using class
print(ravi.show_fee())
print(rahul.show_fee())
Output
Ravi kumar
Rahul Singh
Ravi fee is: 2500
Rahul fee is: 2500
Behind the code
In the above example, we defined the
@classmethod
fee_increment(cls)
, here the
cls
represent the class itself, not the object. So when we call the
Student4Grade.fee_increment()
statement it invoked the
fee_increment(cls)
method and it set the fee to
cls.fee += 200
. And the fee change can be seen in every class object
ravi
and
rahul
.
Python
@staticmethod
Methods
Sometimes we define a method inside a function that does not use class and object property. In that case, we use static methods. Similar to the
@classmethod
@staticmthod
is also a decorator and unlike regular methods and
@classmethod
it neither binds the method with object nor with class.
It can be treated as a simple function inside the class that does not use
self
or
cls
property. As it does not bind the method with object and class, this means we can not use any class property or method inside it.
Example
class Student4Grade:
fee = 2300
def __init__(self, fname, lname, age):
self.fname = fname
self.lname= lname
self.age = age
def fullname(self):
return self.fname + " "+ self.lname
@classmethod
def fee_increment(cls): #cls is Student4Grade
cls.fee += 200 # equivalent to Student4Grade.fee
def show_fee(self):
return f"{self.fname} fee is: {self.fee}"
@staticmethod
def is_student():
return True
rahul = Student4Grade("Rahul", "Singh", 10)
ravi = Student4Grade("Ravi", "kumar", 9)
print(ravi.is_student()) #True
print(rahul.is_student()) #True
Behind the code
In the above example the
@staticmethod
is_student()
can be called using object
ravi
and
rahul
, but it can not use their properties and methods. Because when the is_student() function is invoked, the interpreter does not know which object is calling it.
Head to Head comparison
Regular Method (self) | @classmethod (cls) | @staticmethod() |
Normal methods inside the class | decorator methods | decorator methods |
Bind the method with a specific object. | Bind the method with the complete class. | Do not bind the method with object and class. |
method first argument must be
self
|
method first argument must be
cls
|
Does not require an argument. |
Summary
-
Normal methods are used to bind the method with an object where
self
represent the object/instance itself. -
Class Method is created using
@classmethod
decorator, and it binds the method to the class itself usingcls
argument. -
Static Method is created using
@staticmethod
decorator, and it does not bind the method with class or object.
People are also reading:
Leave a Comment on this Post