A Python class can hold three kinds of method, and what actually separates them is the object each one receives when it is called: an instance method gets the instance, a classmethod gets the class, and a staticmethod gets nothing at all. Choosing the right one of method, classmethod and staticmethod is a design decision, not a style preference.
The rule of thumb is short. If the method needs the object's own data, make it an instance method. If it needs the class itself — usually to build an instance — make it a classmethod. If it needs neither, make it a staticmethod or, better, a module-level function.
What makes a method an instance method?
Any method whose first parameter is self. When you call obj.method(...), Python passes obj into self automatically. That is why the first argument never appears at the call site even though it is always in the definition.
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
def describe(self):
return f"{self.celsius} degrees Celsius"
def is_freezing(self):
return self.celsius <= 0
cold = Temperature(-4)
print(cold.describe())
print("freezing?", cold.is_freezing())
print("called on the class, self is missing:")
try:
Temperature.describe()
except TypeError as exc:
print("TypeError:", exc)
Calling the method on the class instead of an instance — Temperature.describe() — leaves self unfilled and raises TypeError. The error message names the missing argument, which is a quick way to see that you called an instance method in the wrong place.
When is a classmethod the right tool?
A classmethod's first parameter is cls, and Python fills it with the class the method was called on. That matters for one specific job above all others: alternative constructors. A classmethod can build an instance and, because it receives the class rather than a hard-coded name, it keeps working when a subclass inherits it.
There is a second, subtler reason the cls parameter exists. Because Python fills it in based on the class the call was made on, a classmethod can be overridden in a subclass to change the behaviour for every instance of that subclass — no per-instance checks required.
That is also why a classmethod is a poor fit for a function that merely happens to live in a class body. If it never touches cls, then cls is decoration, and a module-level function anyone can import would serve better.
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
@classmethod
def from_string(cls, text):
return cls(float(text))
@classmethod
def from_fahrenheit(cls, value):
return cls((value - 32) * 5 / 9)
class Kelvin(Temperature):
pass
print(type(Temperature.from_string("21.5")).__name__)
print(type(Kelvin.from_string("21.5")).__name__)
print("fahrenheit 212 is", Temperature.from_fahrenheit(212).celsius, "Celsius")
Look at from_string. It calls cls(...), not Temperature(...). That single character of care means a subclass that inherits from_string produces instances of the subclass, not of the parent. If you have ever found yourself overriding a classmethod only to change the class name inside it, this is the fix.
A classmethod is also the natural home for factory methods that need the class for some other reason — a registry of subclasses, a shared configuration value defined on the class, an alternative parsing rule.
When should you reach for a staticmethod?
A staticmethod takes no implicit first argument. It cannot see the instance or the class, so it is a function that happens to live inside a class body. Its legitimate uses are narrow: a helper that is clearly related to the class's domain, or a way to offer an alternative construction that needs no instance state at all.
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@staticmethod
def is_valid_size(width, height):
return width > 0 and height > 0
def area(self):
return self.width * self.height
print(Rectangle.is_valid_size(3, 4))
print(Rectangle.is_valid_size(3, -4))
print("area of a good one:", Rectangle(3, 4).area())
Notice that is_valid is called on the class and never receives anything automatically. If you find yourself writing a staticmethod that never uses cls and never uses self, and nothing about it feels tied to the class, move it out to a module-level function. Grouping unrelated helpers inside a class makes the class look busier than it is.
How do you choose between the three?
| Kind | First parameter | Use it when |
|---|---|---|
| instance method | self | the result depends on this object's data |
| classmethod | cls | you need the class, e.g. to build an instance |
| staticmethod | none | the logic is class-related but standalone |
class Temperature:
unit = "C"
def __init__(self, celsius):
self.celsius = celsius
def describe(self):
return f"{self.celsius}{self.unit}"
@classmethod
def from_fahrenheit(cls, value):
return cls((value - 32) * 5 / 9)
@staticmethod
def is_valid(celsius):
return -273.15 <= celsius <= 1000
print(Temperature(21.5).describe())
print(Temperature.from_fahrenheit(70).describe())
print("valid:", Temperature.is_valid(21.5), "| nonsense:", Temperature.is_valid(-400))
print("the class itself knows its unit:", Temperature.unit)
That last snippet shows how the three coexist. describe needs the instance. from_fahrenheit needs the class so it can build the right kind of object. is_valid needs neither, so it stays out of the way of the object entirely.
There is a fourth thing you can decorate, worth mentioning so the list is complete: @property. It turns a method into one you access like an attribute, without parentheses. It is how you offer read-only derived values, and it is covered in detail later in the tutorial.
Staticmethods also have a limitation that catches people out. They cannot be overridden in a way that lets a subclass change their behaviour, because there is nothing to bind them to. If you find yourself wanting a staticmethod to behave differently for a subclass, that is a signal it should have been a classmethod all along.
One caution about staticmethods: they are not overridable in a useful way, and they cannot be called on an instance in a way that gives them context. If a subclass needs different behaviour, a classmethod is almost always the better choice, because it can see which class it is running for.
| Call style | What reaches the method | Works? |
|---|---|---|
obj.instance_method(x) | obj as self | yes |
Cls.classmethod(x) | Cls as cls | yes |
obj.classmethod(x) | type(obj) as cls | yes |
Cls.staticmethod(x) | nothing | yes |
Cls.instance_method(x) | nothing — self is missing | no, raises TypeError |
Rule of thumb
- Instance method: first parameter
self, needs the object's data. - Classmethod: first parameter
cls, best for alternative constructors that survive subclassing. - Staticmethod: no implicit parameter, a domain-related helper that needs no context.
- Call an instance method on an instance, a classmethod on the class, and a staticmethod on either.
- If a staticmethod never touches the class, a plain module-level function is the honest choice.
Try it yourself: give a class three kinds of method
Build a BankAccount class with a currency, a balance and an owner. Add an instance method deposit(amount) that changes the balance and returns the new value. Add a classmethod from_string(text) that parses something like "Asha:250" and returns a new account. Add a staticmethod is_valid_amount(amount) that reports whether a number is a sensible deposit.
Then use each one the correct way: account.deposit(100), BankAccount.from_string("Ben:90"), BankAccount.is_valid_amount(-5). Finally, subclass it as SavingsAccount and check that SavingsAccount.from_string("Cara:10") returns a SavingsAccount and not a plain BankAccount — that is the payoff of using cls instead of naming the class directly.