What is the difference between @staticmethod and @classmethod in Python?

In Python, @classmethod and @staticmethod are decorators used to define methods within a class, but they serve different purposes:

1. @classmethod

  • First Parameter: cls (refers to the class itself, not an instance).
  • Purpose:
  • Operate on the class (e.g., modify class-level variables).
  • Create factory methods (alternative constructors).
  • Inherit properly in subclasses (e.g., cls points to the subclass when called from one).
  • Example:
  class MyClass:
      class_var = 0

      @classmethod
      def increment_class_var(cls):
          cls.class_var += 1  # Modifies class-level variable

      @classmethod
      def from_string(cls, data: str):
          # Factory method to create an instance from a string
          return cls(data.split(","))

  # Usage:
  MyClass.increment_class_var()  # Class variable updated
  obj = MyClass.from_string("a,b,c")  # Creates an instance

2. @staticmethod

  • First Parameter: None (no self or cls).
  • Purpose:
  • Act as utility functions related to the class (no access to class/instance state).
  • Group logically related functions under the class namespace.
  • Example:
  class MathUtils:
      @staticmethod
      def add(a: int, b: int) -> int:
          return a + b  # No dependency on class/instance

  # Usage:
  result = MathUtils.add(3, 5)  # Output: 8

Key Differences

Feature@classmethod@staticmethod
First Parametercls (class reference)None
Access to ClassCan modify class stateNo access to class/instance
Use CasesFactory methods, class-level logicUtility functions, helper methods
Inheritancecls adapts to subclassBehavior fixed (no cls/self)

When to Use Which

  • Use @classmethod when you need to:
  • Create alternative constructors (e.g., from_json(), from_csv()).
  • Modify class-level state (e.g., counters, configurations).
  • Use @staticmethod for functions that:
  • Don’t depend on class/instance state (e.g., validation, calculations).
  • Are logically grouped under the class for organization.

Example: Inheritance Behavior

class Parent:
    @classmethod
    def create(cls):
        return cls()  # Uses the subclass if inherited

    @staticmethod
    def log(message):
        print(f"Log: {message}")

class Child(Parent):
    pass

# Classmethod adapts to Child:
child = Child.create()  # Returns a Child instance

# Staticmethod remains unchanged:
Child.log("Hello")  # Output: "Log: Hello"

By choosing the right decorator, you ensure proper access to class/instance data and maintain clean code structure.

Leave a Reply

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