Three ways to define a function inside a class. Each serves a different purpose.

class Demo:
    # ── Instance method (no decorator) ──
    def regular(self, x):
        return f"instance: {self}.{x}"

    # ── Class method ──
    @classmethod
    def clsmtd(cls, x):
        return f"class: {cls}.{x}"

    # ── Static method ──
    @staticmethod
    def static(x):
        return f"static: {x}"

Instance Method — def method(self, ...)

  • Receives self → the instance that called it.
  • Can read/write instance state (self.attr).
  • Needs an object to be called on (or you pass one manually).
obj = Demo()
obj.regular("hi")           # instance: <Demo object>.hi
Demo.regular(obj, "hi")     # same thing, explicit self

Class Method — @classmethod

  • Receives cls → the class itself (or a subclass).
  • Can access/modify class-level state (cls.attr).
  • Polymorphic — if a subclass calls it, cls is the subclass.
Demo.clsmtd("hi")            # class: <class 'Demo'>.hi

class Sub(Demo): pass
Sub.clsmtd("hi")             # class: <class 'Sub'>.hi

Common use: alternative constructors.

class Vector:
    def __init__(self, x, y):
        self.x, self.y = x, y

    @classmethod
    def from_tuple(cls, t):
        return cls(*t)

v = Vector.from_tuple((3, 4))

Static Method — @staticmethod

  • Receives neither self nor cls.
  • Just a plain function namespaced inside the class.
  • Behaves exactly like a module-level function — no access to class or instance.
Demo.static("hi")            # static: hi
obj = Demo()
obj.static("hi")             # static: hi (works on instance too)

Use when the function is conceptually tied to the class but doesn’t need its state (e.g. a helper or conversion that could live outside).

Quick Reference

Decorator First param Bound to Can access instance Can access class
(none) self instance yes yes (via self.__class__)
@classmethod cls class no yes
@staticmethod nothing neither no no

When to Use What

  • Instance method — default choice. The function needs or might need instance data.
  • @classmethod — factory methods, or any function that needs the class (especially for subclass-friendly polymorphism).
  • @staticmethod — the function doesn’t reference self or cls at all. Move it to a module-level function unless it’s so closely tied to the class that namespacing it improves readability.