For beginners who are learning object-oriented programming in Python, it is very essential to have a good grasp over class method and static method for writing more optimized and reusable code.
Also, it is very common for even experienced programmers coming from different languages to get confused between these two.
In this article, we will develop a better understanding of the class method and static methods in Python.
Static Method in Python
A @staticmethod
is a method that knows nothing about the class or instance it was called on unless explicitly given. It just gets the arguments that were passed, no implicit first argument and It’s definition is immutable via inheritance.
In simpler words a @staticmethod
is nothing more than a regular function defined inside a class that doesn't have access to the instance therefore It is callable without instantiating the class.
Syntax:
class ClassName:
@staticmethod
def method_name(arg1, arg2, ...):
...
We use the @staticmethod
decorator for defining a static method in Python, here you can observe that the static method is not taking self as an argument for the method.
Now let's look at an example.
class Myclass():
@staticmethod
def staticmethod():
print('static method called')
As we discussed we can access the static method of a class without creating an object.
Myclass.staticmethod()
Output:
static method called
Although calling the method from a class instance is also possible.
my_obj = Myclass()
my_obj.staticmethod()
Output:
static method called
Great, but when are static methods useful?
The static method helps in achieving encapsulation in Python class since it is not aware of the state of the current instance. Also, static methods make code more readable and reusable and more convenient to import versus module-level functions since each method does not have to be specially imported.
class Person():
@staticmethod
def is_adult(age):
if age > 18:
return True
else:
return False
In the above example, we can check if the person is an adult with or without initiating the class.
Person.is_adult(23)
Output:
True
Class Method in Python
A @classmethod
is a method that receives the class as the implicit first argument, just like an instance method receives the instance. This means you can use the class and its properties inside that method rather than a particular instance.
So @classmethod
is basically a method of a class having access to every attribute of the class it was called on. Therefore a class method is a method that is bound to the class and not the object of the class.
Syntax:
class Class:
@classmethod
def method(cls, arg1, arg2, ...):
...
The @classmethod
decorator is used for creating a class methods and cls
should be the first argument of every class method.
class MyClass:
@classmethod
def classmethod(cls):
print('Class method called')
@classmethod
functions are also callable without instantiating the class, but its definition follows Subclass, not Parent class, via inheritance.
MyClass.classmethod()
Output:
Class method called
So when to use class methods?
@classmethod
are for when you need to have methods that aren't specific to any particular instance, but still, involve the class in some way. The most interesting thing about them is that they can be overridden by subclasses.
So If you want to access a property of a class as a whole, and not the property of a specific instance of that class, use a class method.
class MyClass():
TOTAL_OBJECTS=0
def __init__(self):
MyClass.TOTAL_OBJECTS = MyClass.TOTAL_OBJECTS+1
@classmethod
def total_objects(cls):
print("Total objects: ",cls.TOTAL_OBJECTS)
# Creating objects
my_obj1 = MyClass()
my_obj2 = MyClass()
my_obj3 = MyClass()
# Calling class method
MyClass.total_objects()
Output:
Total objects: 3
Now if we inherit this class into a child class and declare the TOTAL_OBJECTS
variable there and call the class method from child class it will return the total object count for the child class.
class MyClass():
TOTAL_OBJECTS=0
def __init__(self):
MyClass.TOTAL_OBJECTS = MyClass.TOTAL_OBJECTS+1
@classmethod
def total_objects(cls):
print("Total objects: ",cls.TOTAL_OBJECTS)
# Creating objects of parent
classmy_obj1 = MyClass()
my_obj2 = MyClass()
# Creating a child class
class ChildClass(MyClass):
TOTAL_OBJECTS=0
passChildClass.total_objects()
Output:
@classmethod
is used in a superclass to define how that method should behave when it's called by different child classes. Whereas a @staticmethod
is used when we want to return the same thing regardless of the child class that we are calling.
Also, keep a note that calling a @classmethod
involves an additional memory allocation that calling a @staticmethod
or regular function does not.