Python Class Method: Syntax, Usage, and When to Use It
Learn how to declare a python class method, how cls binds to the calling class, and when a class method beats a static method.
What a Class Method Actually Is
A class method is a function bound to a class rather than to an instance of that class. In Python, you declare one with the @classmethod decorator, and its first argument is conventionally named cls. That argument receives the class object itself, not an instance. This is the core difference from a regular instance method, whose first argument, self, receives the instance.
The python class method pattern is most useful when a function needs to know which class it is operating on, but does not need any particular instance's data.
Declaring a Class Method
The syntax is straightforward:
class Order: def __init__(self, order_id, items): self.order_id = order_id self.items = items @classmethod def empty(cls): return cls(None, [])
The @classmethod decorator wraps the function so that calling Order.empty() automatically passes Order as cls. Inside the method, cls can be used to call the constructor, access class attributes, or invoke other class methods. Calling Order.empty() returns an Order instance with order_id set to None and an empty item list.
Unlike self, which is passed only when you call a method on an instance, cls is passed when you call the method on the class itself. You can also call a class method from an instance, and cls will still be the class, not the instance.
How cls Binds to the Calling Class
The most important behavior to understand is that cls is bound to the class through which the method is called, not the class where the method is defined. This makes class methods inheritance-aware.
class Base: @classmethod def create(cls): return cls() class Child(Base): pass obj = Child.create() print(type(obj)) # <class '__main__.Child'>
Because Child.create() passes Child as cls, the method returns a Child instance even though create is defined on Base. If the method had used Base() directly, it would return a Base instance regardless of the caller. This binding behavior is why class methods work well as alternative constructors in class hierarchies.
Class Methods as Alternative Constructors
A common use for a class method is to provide a second way to build an instance, often from data in a different format.
class Temperature: def __init__(self, celsius): self.celsius = celsius @classmethod def from_fahrenheit(cls, fahrenheit): return cls((fahrenheit - 32) * 5 / 9)
Temperature.from_fahrenheit(212) returns a Temperature instance with celsius equal to 100.0. The conversion logic lives in one place, and the method returns the correct class even when called on a subclass. This keeps parsing and conversion code out of __init__, which stays focused on the primary representation.
Class Method vs Static Method
Both @classmethod and @staticmethod can be called without an instance, but they behave differently.
| Aspect | @classmethod | @staticmethod |
|---|---|---|
| First argument | cls, the class | none |
| Access to class state | yes | no |
| Inheritance behavior | cls follows the calling subclass | no class reference |
| Typical use | alternative constructors, class-level factories | utility functions grouped with a class |
Use a class method when the function needs the class: to build an instance, read a class attribute, or respect subclassing. Use a static method when the function is a plain utility that happens to live in the class namespace and needs neither instance nor class data.
A static method cannot call the class constructor without hardcoding the class name, which breaks subclass behavior. If you find yourself writing the class name inside a static method just to create an instance, a class method is the correct choice.
Where Class Methods Commonly Break
The most common mistake is using the class name directly instead of cls. This silently breaks inheritance.
class Base: @classmethod def create(cls): return Base() # hardcodes Base class Child(Base): pass Child.create() # returns Base, not Child
The fix is to use cls:
class Base: @classmethod def create(cls): return cls() Child.create() # returns Child
Another mistake is declaring a class method when the function actually needs instance data. If the method reads or writes self attributes, it should be an instance method. Conversely, using self in a class method raises a TypeError because the first argument is the class, not an instance.
Runtime Cost and Maintainability
Calling a class method involves attribute lookup and passing cls, so it is marginally slower than a direct function call. In practice the overhead is negligible unless the method is called in a tight loop millions of times, in which case the class lookup can be cached in a local variable.
The larger concern is maintainability. A class method that hardcodes its own class name produces subtle bugs in subclasses. A class method that never uses cls is usually better written as a static method or a module-level function, because the class reference adds nothing and makes the intent less clear. Keeping the distinction explicit makes the codebase easier to reason about as the hierarchy grows.