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
@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.
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.
static method called
Although calling the method from a class instance is also possible.
my_obj = Myclass() my_obj.staticmethod()
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.
Class Method in Python
@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.
@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.
class Class: @classmethod def method(cls, arg1, arg2, ...): ...
@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.
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()
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 class my_obj1 = MyClass() my_obj2 = MyClass() # Creating a child class class ChildClass(MyClass): TOTAL_OBJECTS=0 pass ChildClass.total_objects()
Total objects: 0
@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.