What are class methods, static methods, and instance methods?

Python classes support three styles of callable members. They differ in what (if anything) gets passed implicitly as the first argument.

  • Instance method — the default. Receives the instance as self. Operates on per-object state.

  • Class method — decorated with @classmethod. Receives the class as cls. Operates on the class itself or builds instances via alternative constructors.

  • Static method — decorated with @staticmethod. Receives nothing implicit. Logically belongs to the class but doesn’t use self or cls.

Example:

class Pizza:
    def __init__(self, toppings):
        self.toppings = list(toppings)

    def describe(self):                # instance method
        return f"pizza with {self.toppings}"

    @classmethod
    def margherita(cls):               # class method — alternative constructor
        return cls(["tomato", "mozzarella", "basil"])

    @staticmethod
    def is_vegetarian(toppings):       # static method — pure helper
        return all(t not in {"pepperoni", "bacon"} for t in toppings)

p = Pizza.margherita()                # uses classmethod constructor
p.describe()                          # instance method
Pizza.is_vegetarian(["mushroom"])    # static helper

class Employee:
    raise_percentage = 1.05  # Class variable
    _count = 0

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

    # Instance method - accesses instance data
    def apply_raise(self):
        self.salary *= self.raise_percentage

    # Class method - accesses class data, alternative constructor
    @classmethod
    def set_raise_percentage(cls, percentage):
        cls.raise_percentage = percentage

    @classmethod
    def from_string(cls, emp_str):  # Alternative constructor
        name, salary = emp_str.split(',')
        return cls(name.strip(), float(salary.strip()))

    @classmethod
    def get_count(cls):
        return cls._count

    # Static method - utility, no access to class/instance
    @staticmethod
    def is_valid_salary(salary):
        return salary > 0

# Usage
emp = Employee('John', 50000)
emp.apply_raise()                          # Instance method
print(emp.salary)                           # 52500.0

Employee.set_raise_percentage(1.10)          # Class method
emp2 = Employee.from_string('Jane, 60000')  # Alternative constructor
print(Employee.get_count())                  # 2

print(Employee.is_valid_salary(-100))        # Static method: False

apply_raise uses self to modify the instance's salary. set_raise_percentage uses cls to modify the class variable for all instances. from_string is a factory method — it creates an Employee from a different format (string instead of separate arguments). is_valid_salary is a utility that does not need self or cls — it is just a function scoped to the class.

The factory method pattern (from_string) is the most practical use of @classmethod. Know that @staticmethod is just a namespaced function — no access to self or cls.

The self vs cls distinction (instance vs class access) is the core concept.

What are class methods, static methods, and instance methods? | Hiprup