Decoding Python @classmethod and @staticmethod

WHAT YOU LEARN IN THIS TUTORIAL

  • Develop an intuitive understanding of the class methods and static methods in object-oriented Python.

A week ago, I wrote about python classes (inheritance and composition), if you haven’t checked it out, please check it out here.

An Overview of the static and class method.

Let us begin with a simple example.

class GreetMethodName:
    
    def greet(self):
        return " instance", self

    @classmethod
    def class_greet(cls):
        return "classmethod", cls

    @staticmethod
    def static_greet():
        return f"staticmethod"

g = GreetMethodName()
print(g.greet())
print(g.class_greet())
print(g.static_greet())
(' instance', <__main__.GreetMethodName object at 0x7fa24d1a76d8>)
('classmethod', <class '__main__.GreetMethodName'>)
staticmethod

 

Side notes

Method: A function that’s part of a class is a method

Instantiation: Making an object from a class is called instantiation, and you work with instances of a class

Now we can use the class named GreetMethodName to create an object called g.

 g = GreetMethodName()

Instance Method

The greet method on GreetMethodName is a formal instance method and it takes one parameter, self, which points to an instance of GreetMethodName and the class itself when the method is called (<__main__.GreetMethodName object at 0x7fe5dccdf4e0>).

The Class Method

This class_greet is decorated with a @classmethod decorator to signify it as a class method.
Instead of accepting a self parameter, class methods take a cls (class) parameter that points to the class and not the class instance.
The class method takes the class as a parameter to know about the state of that class and because of that can access and modify the class state but not the object state.
You can see it can access the class (<class '__main__.GreetMethodName'> )but not the object instance.

Static Method

This static_greet is decorated with a @staticmethod decorator to signify it as a static method
The static method neither takes self (the object instance) nor cls (the class) implicitly passed as the first argument but they can take a random number of parameters. They behave like plain functions except that you can call them from an instance of the class.
The static method can neither modify the object nor the class state.

Let’s See These Methods in a Simple Application

A simple job application that rejects users that are above 25 years.

from datetime import datetime as dt
import datetime

class JobApp:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def isabove_twentyfive(self):
        if self.age > 25:
            return ("you are above the age requirement")
        else:
            return (f"Welcome!,{self.name}, you can continue")
        
    @staticmethod
    def deduce_birthday(name, year):
        age= dt.now().year - year
        return(name, age)
        

    @classmethod
    def compute_age_diff(cls,name, year):
        age= dt.now().year - year
        return cls(name, age)



John = JobApp.deduce_birthday("John", 1990)
print(John.__str__())
print(John.isabove_twentyfive())
('John', 30)

AttributeError: 'tuple' object has no attribute 'isabove_twentyfive'

You can see that @staticmethod knows nothing about the class, so it has no access to the class state that is why

  • It can’t access the __str__() method, (string representations of class instances).
  • We ran into attribute error because we can’t access the isabove_twentyfive method.
Jerry = JobApp.compute_age_diff("Jerry", 1998)
print(Jerry.__str__())
print(Jerry.isabove_twentyfive())
Employee name :Jerry
Welcome!,Jerry, you can continue

The @classmethod knows about the class state because of that it can access the __str__() method, (string representations of class instances) and isabove_twentyfive method.

Final takeaways
  • Class methods have access to the class state via cls.
  • A static method is a method that knows nothing about the class or object state, it works like a regular function but belong to the class’s namespace.

 

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *