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).
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__.
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'])
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.
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
Choosing the right one
Need to read or change
self.somethingon 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
selforclsat all? Use a static method.
Method type | Decorator | First param | Access instance state | Access class state | Typical use |
|---|---|---|---|---|---|
Instance method | none |
| Yes | Yes (via | Regular behavior tied to one object |
Class method |
|
| No | Yes | Alternative constructors, class-wide state |
Static method |
| none | No | No | Utility/helper logically grouped with the class |