100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Class Methods and Static Methods in Python

The difference between instance methods, @classmethod (receives cls), and @staticmethod (receives neither self nor cls), with practical use cases.

OOP AdvancedIntermediate11 min readJul 7, 2026
Analogies

1. Introduction

Python classes support three kinds of methods: instance methods (the default, taking self), class methods (decorated with @classmethod, taking cls), and static methods (decorated with @staticmethod, taking neither). Choosing the right kind clarifies intent: does the method need per-instance state, class-level state, or no state from the class at all?

🏏

Cricket analogy: A player's personal batting average (instance method) needs that player's own stats, the team's overall net run rate (classmethod) needs squad-wide data, and a pitch-length conversion utility (staticmethod) needs no player or team data at all.

Class methods are commonly used for alternative constructors (factory methods) and for operations on class-level data shared by all instances. Static methods are used for utility functions that are logically related to the class but don't need access to the class or any instance.

🏏

Cricket analogy: A selector using a classmethod like Player.from_domestic_stats(name) builds a new player profile as an alternative constructor, while a staticmethod like is_valid_jersey_number(37) just checks a rule with no player data needed.

2. Syntax

python
class MyClass:
    class_attr = 0

    def instance_method(self):
        # receives the instance automatically
        return self.class_attr

    @classmethod
    def class_method(cls, value):
        # receives the class automatically
        cls.class_attr = value
        return cls.class_attr

    @staticmethod
    def static_method(x, y):
        # receives nothing automatically
        return x + y

3. Explanation

An instance method's first parameter (self) is bound automatically to the instance it's called on, so it can read and mutate per-object state. A class method's first parameter (cls) is bound to the class itself (not an instance), so it can read/mutate class-level attributes and — importantly — can be used as a factory that returns cls(...), which correctly creates subclass instances when called via a subclass. A static method receives no automatic first argument at all; it behaves like a plain function that's simply namespaced inside the class for organizational purposes.

🏏

Cricket analogy: self is like a specific player adjusting his own batting stance, cls is like team management updating the squad-wide training schedule and even correctly applying it to a newly promoted A-team using cls(...), while a staticmethod is like a pitch-report lookup that ignores both player and team entirely.

Rule of thumb: use an instance method when you need self (per-object data); use @classmethod when you need cls (class-level data or to build alternative constructors like from_string(...) that should honor subclassing); use @staticmethod when the function is thematically related to the class but touches neither instance nor class state — it could technically live outside the class.

Gotcha: a @classmethod that mutates a class attribute (e.g. cls.raise_pct = value) changes it for every instance, including ones already created, because instances look up the attribute on the class unless they have their own instance attribute of the same name shadowing it. This is different from an instance method that only mutates self.some_attr, which affects just that one object.

4. Example

python
import datetime


class Employee:
    raise_pct = 1.05
    count = 0

    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        Employee.count += 1

    def apply_raise(self):
        self.salary = int(self.salary * self.raise_pct)

    @classmethod
    def from_string(cls, emp_str):
        name, salary = emp_str.split("-")
        return cls(name, int(salary))

    @classmethod
    def set_raise_pct(cls, amount):
        cls.raise_pct = amount

    @staticmethod
    def is_workday(day):
        return day.weekday() < 5


e1 = Employee("Alice", 50000)
e2 = Employee.from_string("Bob-60000")

Employee.set_raise_pct(1.10)
e1.apply_raise()

print(e1.name, e1.salary)
print(e2.name, e2.salary)
print(Employee.count)
print(Employee.is_workday(datetime.date(2024, 6, 3)))  # Monday
print(Employee.is_workday(datetime.date(2024, 6, 8)))  # Saturday

5. Output

text
Alice 55000
Bob 60000
2
True
False

6. Key Takeaways

  • Instance methods take self and operate on per-object state; they're the default kind of method.
  • @classmethod methods take cls and operate on class-level state or build alternative constructors via cls(...).
  • @staticmethod methods take neither self nor cls — they're plain functions grouped inside the class namespace.
  • Using cls(...) instead of ClassName(...) inside a classmethod factory ensures subclasses create instances of themselves.
  • Mutating a class attribute through a classmethod affects all instances that haven't shadowed it with their own instance attribute.
  • Choose the method type based on what state the method actually needs: object, class, or none.

Practice what you learned

Was this page helpful?

Topics covered

#Python#PythonProgrammingStudyNotes#Programming#ClassMethodsAndStaticMethodsInPython#Class#Methods#Static#Syntax#OOP#Functions#StudyNotes#SkillVeris