Python staticmethod()

Python @staticmethod is a decorator used to create a static method within a class. Static methods are bound to the class itself, not to instances (objects) of the class. They don’t have implicit access to the instance (self) or the class (cls). Static methods are essentially like regular functions defined within a class’s namespace for organizational purposes.

@staticmethod() Syntax

Using the @staticmethod decorator

class MyClass:
    @staticmethod
    def my_static_method(arg1, arg2, ...):
        # Method body
        # ...

Using staticmethod() function (less common)

class MyClass:
    def my_method(arg1, arg2, ...):
        # Method body
        # ...
    my_static_method = staticmethod(my_method)

Syntax Explanation

  • (Decorator Form): The @staticmethod decorator is placed above the method definition.
  • (Decorator Form): The my_static_method is defined as a regular function. It does not take self or cls as the first argument.
  • (Function Form): Regular method my_method is defined.
  • (Function Form): staticmethod(my_method) converts my_method into a static method and assigns it to my_static_method. This form is less common; the decorator is generally preferred.

Example 1: Python @staticmethod()

class MathUtils:
    @staticmethod
    def add(x, y):
        return x + y

    @staticmethod
    def multiply(x, y):
        return x * y

print(MathUtils.add(5, 3))
print(MathUtils.multiply(2, 4))

Code Explanation

  • Line 1: Class MathUtils is defined as group-related utility functions.
  • Line 2: The @staticmethod decorator marks the add method as static.
  • Line 3: The add method takes two arguments, x and y, and returns their sum.
  • Line 6: The @staticmethod decorator marks the multiply method as static.
  • Line 7: The multiply method takes two arguments, x and y, and returns their product.
  • Line 9: MathUtils.add(5, 3) calls the static add method directly using the class name. The result (8) is printed.
  • Line 10: MathUtils.multiply(2, 4) calls the static multiply method. The result (8) is printed.

Output

8
8


What is a Static Method?

A static method is a method that belongs to a class rather than an instance of the class. Key characteristics:

  • It does not have access to the instance (self) or the class (cls) implicitly.
  • It’s called using the class name (e.g., ClassName.static_method()).
  • It’s used for utility functions or operations related to the class but not dependent on specific instance data.

When Do You Use Static Methods?

Static methods are helpful when:

  • You have utility functions logically related to a class but don’t need access to instance or class data.
  • You want to group related functions within a class’s namespace without requiring an instance of the class.

Example 2: Create a Static Method using @staticmethod()

class MyClass:
    def my_regular_method():
        print("This is a regular function.")

    my_static_method = staticmethod(my_regular_method)

MyClass.my_static_method()

Code Explanation

  • Line 1: Class MyClass is defined.
  • Line 2: Regular function my_regular_method is defined.
  • Line 5: staticmethod(my_regular_method) converts the regular function into a static method and assigns it to my_static_method.
  • Line 7: Static method is called using the class name.

Output

This is a regular function.


Example 3: Create a Utility Function as a Static Method

class StringUtils:
    @staticmethod
    def is_palindrome(s):
        s = s.lower()
        return s == s[::-1]

print(StringUtils.is_palindrome("madam"))
print(StringUtils.is_palindrome("hello"))

Code Explanation

  • Line 1: A class StringUtils is defined to group string-related utility functions.
  • Line 2: The @staticmethod decorator marks is_palindrome as a static method.
  • Line 3: is_palindrome takes a string s, converts it to lowercase, and checks if it’s the same when reversed (using slicing [::-1]).
  • Line 6: Static method uses the class name to check if “madam” is a palindrome (True).
  • Line 7: Static method checks if “hello” is a palindrome (False).

Output

True
False


Example 4: Having a Single Implementation (How Does Inheritance Work with Static Method?)

class Animal:
    @staticmethod
    def make_sound():
        print("Generic animal sound")

class Dog(Animal):
    @staticmethod
    def make_sound():
        print("Woof!")

Animal.make_sound()
Dog.make_sound()

Code Explanation

  • Line 1: Base class Animal is defined with a static method make_sound.
  • Line 5: A subclass Dog is defined, also with a static method make_sound.
  • Line 9: Animal.make_sound() calls the static method of the Animal class.
  • Line 10: Dog.make_sound() calls the static method of the Dog class.

Output

Generic animal sound
Woof!


Example 5: Advanced Example: Factory Method using @staticmethod

class Pizza:
    def __init__(self, ingredients):
        self.ingredients = ingredients

    def __repr__(self):
        return f"Pizza({self.ingredients})"

    @staticmethod
    def margherita():
        return Pizza(['mozzarella', 'tomatoes'])

    @staticmethod
    def pepperoni():
        return Pizza(['mozzarella', 'pepperoni', 'tomatoes'])

print(Pizza.margherita())
print(Pizza.pepperoni())

Code Explanation

  • Line 1: A Pizza class is defined.
  • Line 2: __init__ initializes the ingredients list.
  • Line 5: __repr__ provides a string representation of the Pizza object.
  • Line 8: The @staticmethod decorator is used to define margherita as a static method. This method acts as a factory method, creating and returning a Pizza object with specific ingredients.
  • Line 12: The pepperoni static method is another factory method, creating a Pizza with different ingredients.
  • Line 15: Pizza.margherita() calls the static factory method to create a margherita pizza.
  • Line 16: Pizza.pepperoni() calls the static factory method to create a pepperoni pizza.

Note: Factory methods are a design pattern where a method is responsible for creating objects. Using @staticmethod for factory methods is a common practice when the object creation logic is related to the class but doesn’t depend on a specific instance.

Output

Pizza([‘mozzarella’, ‘tomatoes’])
Pizza([‘mozzarella’, ‘pepperoni’, ‘tomatoes’])


Also Read

Python enumerate()

Python filter()