classmethod
staticmethod
python

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

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

@staticmethod and @classmethod both define methods on a class, but they receive different context and solve different design problems. staticmethod behaves like a namespaced utility function, while classmethod receives the class object and is often used for alternate constructors or class-level behavior. Choosing correctly keeps APIs extensible and inheritance-friendly.

Core Binding Difference

A normal instance method receives self. The two decorators change that binding:

  • @staticmethod receives no automatic first argument.
  • @classmethod receives cls as first argument.
python
1class Demo:
2    @staticmethod
3    def s(x):
4        return x * 2
5
6    @classmethod
7    def c(cls, x):
8        return cls.__name__, x * 2
9
10
11print(Demo.s(3))
12print(Demo.c(3))

This binding difference drives most design decisions.

When to Use @staticmethod

Use static methods when logic belongs conceptually to class domain but does not need class or instance state.

python
1class MathUtils:
2    @staticmethod
3    def clamp(value: float, low: float, high: float) -> float:
4        return max(low, min(high, value))
5
6
7print(MathUtils.clamp(12, 0, 10))

This could be a module-level function too. staticmethod is mainly an organizational choice.

Good static method traits:

  • pure utility logic
  • no dependency on mutable class variables
  • no need for subclass-specific behavior

When to Use @classmethod

Use class methods when behavior should vary with subclass or when constructing class instances from alternative inputs.

python
1class User:
2    def __init__(self, name: str, email: str):
3        self.name = name
4        self.email = email
5
6    @classmethod
7    def from_csv(cls, line: str):
8        name, email = line.strip().split(",")
9        return cls(name=name, email=email)
10
11
12u = User.from_csv("Ava,[email protected]")
13print(u.name, u.email)

Because method calls cls(...), subclasses automatically get correct instance type when they inherit this constructor.

Inheritance Behavior Difference

Inheritance highlights why class methods are powerful.

python
1class Animal:
2    kind = "animal"
3
4    @classmethod
5    def create(cls, name: str):
6        obj = cls()
7        obj.name = name
8        return obj
9
10
11class Dog(Animal):
12    kind = "dog"
13
14
15a = Animal.create("generic")
16d = Dog.create("milo")
17
18print(type(a).__name__, a.kind)
19print(type(d).__name__, d.kind)

Dog.create produces Dog instance because cls refers to subclass at call time.

A static method cannot do this automatically unless subclass type is passed manually.

Practical API Design Patterns

Common classmethod patterns:

  • alternate constructors from JSON, CSV, environment, or DB row
  • class-level caches or registries
  • factory behavior requiring subclass-aware dispatch

Common staticmethod patterns:

  • validation helpers
  • deterministic text formatting
  • small conversion utilities near model code

If method reads or mutates class state, classmethod is usually the right choice.

Interaction with Dataclasses and Validation

In dataclass-heavy code, class methods are often used for richer construction flows.

python
1from dataclasses import dataclass
2
3
4@dataclass
5class Config:
6    host: str
7    port: int
8
9    @classmethod
10    def from_env(cls, env: dict):
11        return cls(
12            host=env.get("APP_HOST", "localhost"),
13            port=int(env.get("APP_PORT", "8080")),
14        )
15
16    @staticmethod
17    def validate_port(port: int) -> bool:
18        return 1 <= port <= 65535
19
20
21cfg = Config.from_env({"APP_HOST": "127.0.0.1", "APP_PORT": "9000"})
22print(cfg)
23print(Config.validate_port(cfg.port))

This separation keeps construction and validation concerns clear.

Testing and Mocking Considerations

Both method types are easy to test, but semantics differ:

  • static methods are usually pure and isolated
  • class methods may depend on class attributes or subclass overrides

When refactoring, class methods preserve polymorphism better than static methods in inheritance-heavy designs.

Common Pitfalls

A common pitfall is using staticmethod for alternate constructors, which blocks subclass-friendly instantiation. Another is using classmethod for utility logic that never touches class state, adding unnecessary complexity. Teams also sometimes convert module-level functions into static methods only for style consistency, reducing reuse across modules. Finally, unclear method intent can confuse API users who expect instance behavior from class-level methods.

Summary

  • @staticmethod has no automatic self or cls binding.
  • @classmethod receives cls and supports subclass-aware behavior.
  • Use static methods for utility logic independent of class state.
  • Use class methods for alternate constructors and class-level workflows.
  • Choose based on semantic intent, not decorator popularity.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.