PythonMethods (instance, class, static)

Methods (instance, class, static)

Python classes support three different kinds of methods, and each one gets a different "first argument" automatically, which changes what it can access. Understanding the difference between instance methods, class methods, and static methods is essential for writing classes that are both correct and easy to reason about.

Instance methods

Instance methods are the default and by far the most common kind. They take self as their first parameter, which Python fills in automatically with the object the method was called on. Because they receive self, instance methods can read and modify that specific object's instance variables, and they can also reach the class through self.__class__ or type(self).

Python
class Counter:
    def __init__(self, start=0):
        self.value = start

    def increment(self, amount=1):
        self.value += amount
        return self.value


c = Counter()
c.increment()
c.increment(5)
print(c.value)
6
Class methods

A class method is marked with the @classmethod decorator and takes cls (the class itself) as its first parameter instead of self. It does not automatically receive any particular instance, so it cannot directly touch instance state — but it can read or set class variables, and, very usefully, it can call cls(...) to build and return a new instance. This makes class methods the standard tool for writing alternative constructors: extra ways to build an object besides the default __init__.

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

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

    @classmethod
    def margherita(cls):
        # Builds and returns a normal Pizza instance
        return cls(["mozzarella", "tomatoes"])

    @classmethod
    def from_string(cls, csv_ingredients):
        # Another alternative constructor, parsing a string of ingredients
        ingredients = [item.strip() for item in csv_ingredients.split(",")]
        return cls(ingredients)


standard = Pizza(["cheese", "pepperoni"])
classic = Pizza.margherita()
custom = Pizza.from_string("mushrooms, olives, feta")

print(standard)
print(classic)
print(custom)
Pizza(['cheese', 'pepperoni'])
Pizza(['mozzarella', 'tomatoes'])
Pizza(['mushrooms', 'olives', 'feta'])
Why cls instead of the class name?
Using `cls(...)` rather than hardcoding `Pizza(...)` means the class method still works correctly if a subclass inherits it — `cls` will be the subclass, not always `Pizza`, so `SomeSubclass.margherita()` returns a `SomeSubclass` instance rather than a plain `Pizza`.
Static methods

A static method is marked with @staticmethod and receives no automatic first argument at all — no self, no cls. It behaves like a plain function that just happens to live inside the class's namespace, usually because it is logically related to the class even though it doesn't need to read or write any instance or class state. A common use is a validation or utility helper.

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

    @staticmethod
    def is_valid_ingredient(name):
        # Doesn't need self or cls — it's a pure utility check
        banned = {"pineapple", "ketchup"}
        return isinstance(name, str) and name.lower() not in banned


print(Pizza.is_valid_ingredient("mozzarella"))
print(Pizza.is_valid_ingredient("pineapple"))

# Static methods can also be called on an instance
p = Pizza(["cheese"])
print(p.is_valid_ingredient("olives"))
True
False
True
Note
You can call a class method or static method either on the class (`Pizza.margherita()`) or on an instance (`p.margherita()`) — the result is the same either way, since neither one depends on a specific instance being passed implicitly (`cls`/no-arg lookups work the same regardless of what you called them through).
Choosing the right one
  • Need to read or change self.something on a specific object? Use an instance method.

  • Building an object in an alternative way, or need access to cls (e.g. class-level counters, registries)? Use a class method.

  • Writing a helper that's related to the class but doesn't touch self or cls at all? Use a static method.

Method type

Decorator

First param

Access instance state

Access class state

Typical use

Instance method

none

self

Yes

Yes (via self.__class__)

Regular behavior tied to one object

Class method

@classmethod

cls

No

Yes

Alternative constructors, class-wide state

Static method

@staticmethod

none

No

No

Utility/helper logically grouped with the class