Python has three types of methods inside a class, and the only difference is what they get access to. Let’s break them down.
def method(self)
def method(cls)
def method()
Instance Methods (Regular)
The default. They take self as the first argument, giving access to the instance’s data.
class Pizza:
def __init__(self, size, toppings):
self.size = size
self.toppings = toppings
def describe(self): # instance method
return f"{self.size} pizza with {', '.join(self.toppings)}"
p = Pizza("large", ["mushrooms", "olives"])
print(p.describe()) # large pizza with mushrooms, olives
Class Methods (@classmethod)
They take cls instead of self. They work on the class, not a specific instance. The most common use is the factory pattern — alternative ways to create objects.
class Pizza:
def __init__(self, size, toppings):
self.size = size
self.toppings = toppings
@classmethod
def margherita(cls): # factory method
return cls("medium", ["mozzarella", "tomato", "basil"])
@classmethod
def pepperoni(cls):
return cls("large", ["mozzarella", "pepperoni"])
p = Pizza.margherita() # no need to remember exact toppings
Notice we use cls(...) instead of Pizza(...). This matters for inheritance — if a subclass calls margherita(), cls will be the subclass, not Pizza.
Static Methods (@staticmethod)
They don’t take self or cls. They’re just regular functions that happen to live inside the class because they’re logically related.
class Pizza:
@staticmethod
def validate_topping(topping): # utility function
valid = ["mushrooms", "olives", "pepperoni", "mozzarella"]
return topping.lower() in valid
print(Pizza.validate_topping("Olives")) # True
When to Use Each
- Instance method — when we need to read or modify the object’s state (
self.something) - Class method — when we need the class itself (factory methods, alternative constructors)
- Static method — when the logic is related to the class but doesn’t need the instance or class reference. It’s basically a namespaced utility function
A good rule of thumb: start with instance methods. Only reach for @classmethod or @staticmethod when we genuinely don’t need access to the instance or want an alternative constructor.
In simple language, instance methods know about the object, class methods know about the class, and static methods know about neither — they’re just functions wearing the class’s uniform.