Static vs. instance methods — the basics

Not every method a class needs actually depends on a specific instance — and Python has a distinct way to say so, worth understanding once plain instance methods feel comfortable.

Beginner

3 min read

The default: an instance method needs self

class Circle:
    def __init__(self, radius):
        self.radius = radius
 
    def area(self):                      # instance method — needs self
        return 3.14159 * self.radius ** 2

Every method covered in the classes-and-objects lesson takes self as its first parameter, because it operates on a specific instance's data — area() needs self.radius to know which circle's area to compute. This is the default and by far the most common kind of method: most methods genuinely need to know which instance they're operating on.

A static method: doesn't need any instance at all

class Circle:
    def __init__(self, radius):
        self.radius = radius
 
    @staticmethod
    def is_valid_radius(value):
        return value > 0
 
Circle.is_valid_radius(5)     # True — called on the class, no instance needed
Circle.is_valid_radius(-2)    # False

@staticmethod marks a method that doesn't need self (or any instance) at all — it's a plain function that happens to live inside the class's namespace because it's conceptually related to it. is_valid_radius doesn't need to know about any particular circle; it's just a validation check that's logically grouped with Circle rather than floating around as an unrelated top-level function. It can be called directly on the class itself (Circle.is_valid_radius(5)), without ever creating an instance.

A class method: needs the class itself, not a specific instance

class Circle:
    def __init__(self, radius):
        self.radius = radius
 
    @classmethod
    def unit_circle(cls):
        return cls(radius=1)          # cls is Circle here — builds and returns a Circle
 
unit = Circle.unit_circle()
unit.radius   # 1

@classmethod marks a method that receives cls (the class itself) instead of self. Its most common real use is an alternative constructor — a different, named way to build an instance, beyond the plain Circle(radius) call. unit_circle() builds and returns a Circle internally, using cls rather than hardcoding Circle(...) directly — which matters once inheritance is involved: if a subclass calls unit_circle(), cls refers to the subclass, so the classmethod correctly builds an instance of the subclass, not the parent.

Picking the right one: a quick decision guide

Most methods you write will be plain instance methods — that's the normal case, and reaching for @staticmethod or @classmethod is the exception, not the default. The signal for @staticmethod is a method whose body never touches self; the signal for @classmethod is usually "I need an alternative way to construct this class."

Why this distinction is worth knowing, not just trivia

Understanding which kind of method you're looking at tells you something real about what it can and can't do before reading its body: an instance method can read and modify that specific object's data; a classmethod can build new instances or read class-level (shared) state; a staticmethod can do neither — it's genuinely independent of any instance or the class's own state, just grouped there for organization. Recognizing @staticmethod/@classmethod on sight, rather than treating every method as "probably needs self," is a small but real jump in reading unfamiliar class code fluently.

Further reading

Check your understanding

A quick comprehension check — not tracked, not graded, just for you.

1. What's the tell-tale sign a method should be marked @staticmethod?

2. Why does @classmethod receive cls instead of self?

3. What's the most common real use of a classmethod?

4. What kind of method should you default to writing, unless there's a specific reason not to?