Back to Blog
Python

Python classmethod Decorator Explained with Examples

Learn how the python classmethod decorator works, how it differs from staticmethod, and when to use it for factory methods and inheritance.

classmethodpython decoratorsstaticmethodfactory methodsinheritance
Diagram showing a classmethod decorator binding a method to the class rather than an instance, with a class box and an arrow pointing to the class

The python classmethod decorator transforms a method so that it receives the class as its first argument instead of an instance. This is a core tool for writing factory methods, alternative constructors, and class-level logic that needs to respect inheritance. Understanding how it binds to the class rather than an instance is key to using it correctly.

What the classmethod Decorator Does

When you apply @classmethod to a method, the method is bound to the class itself. The first parameter, conventionally named cls, refers to the class on which the method is called. This happens regardless of whether the method is invoked on the class or on an instance.

class MyClass: @classmethod def create(cls, value): return cls(value) def __init__(self, value): self.value = value obj = MyClass.create(10) print(obj.value) # 10

The create method receives MyClass as cls and returns a new instance. If you call obj.create(20) on an existing instance, cls is still MyClass, not the instance. This is a fundamental difference from instance methods, which receive self.

classmethod vs staticmethod vs Instance Methods

To decide when to use @classmethod, you need to compare it with the other two method types. The table below summarizes the key differences.

Method typeFirst argumentAccess to instance stateAccess to class stateTypical use
Instance methodselfYesVia self.__class__Behavior that depends on instance data
Class methodclsNoYesFactory methods, alternative constructors
Static methodnoneNoNoUtility functions that don't need class context

A class method can access class attributes and other class methods through cls. It cannot access instance attributes because it does not have a reference to a specific instance. A static method, on the other hand, has no automatic reference to either the class or an instance. It behaves like a plain function but lives inside the class namespace.

Using classmethod for Alternative Constructors

The most common use of @classmethod is to provide alternative ways to create an instance. This is often called a factory method. Instead of overloading __init__, you define a class method that parses different input formats and returns an instance of the class.

class Person: def __init__(self, name, age): self.name = name self.age = age @classmethod def from_birth_year(cls, name, birth_year): age = 2025 - birth_year return cls(name, age) p = Person.from_birth_year("Alice", 1990) print(p.age) # 35

Here, from_birth_year computes the age and then calls cls(name, age). Using cls instead of the hard-coded class name ensures that if you call this method on a subclass, it returns an instance of that subclass, not the parent class.

How classmethod Behaves with Inheritance

The real power of @classmethod emerges in inheritance. Because cls is the actual class on which the method is called, polymorphic behavior works naturally.

class Animal: @classmethod def make_sound(cls): return cls().sound() def sound(self): return "Generic sound" class Dog(Animal): def sound(self): return "Woof" print(Dog.make_sound()) # Woof

When you call Dog.make_sound(), cls is Dog, so cls().sound() invokes Dog.sound(). A static method would not have access to cls and would have to hard-code the class, breaking this polymorphic behavior. This is why class methods are preferred over static methods when the method needs to be overridden or when it must work with subclasses.

Common Mistakes and Edge Cases

One frequent mistake is using @classmethod for a method that actually needs instance data. Because cls does not give you access to instance attributes, you cannot read self.attribute inside a class method. If you need instance state, use an instance method instead.

Another edge case is calling a class method on an instance. It works, but the instance is ignored. This can be confusing if you expect the instance to be passed. For example:

class Counter: count = 0 @classmethod def increment(cls): cls.count += 1 c = Counter() c.increment() print(Counter.count) # 1

The increment method modifies the class attribute, not the instance. If you need to modify an instance attribute, this will not work.

Also, be careful when using cls to create new instances. If the class has required __init__ parameters, the class method must provide them. If a subclass changes the constructor signature, the class method may break unless it is overridden.

Performance and Maintainability Considerations

From a performance perspective, @classmethod has a tiny overhead compared to a static method because it passes an extra argument. In practice, this is negligible unless you are calling it billions of times in a hot loop. The more important consideration is maintainability. Using cls instead of a hard-coded class name keeps your code DRY and makes subclassing easier.

Class methods are also useful for managing class-level state. Because they can modify class attributes, they provide a controlled way to update shared state. However, this can lead to subtle issues if multiple subclasses share mutable class attributes. Each subclass gets its own copy of class attributes only when they are assigned, not when they are mutated in place. For example:

class A: items = [] @classmethod def add(cls, item): cls.items.append(item) class B(A): pass B.add("x") print(A.items) # ['x']

Because items is a list and append mutates it in place, both A and B share the same list. If you want each subclass to have its own list, you need to assign a new list in the class method, not mutate the existing one. This is a common pitfall when using class methods for state management.

When deciding between @classmethod and @staticmethod, choose @classmethod when you need access to the class for polymorphism or when the method should be overridden in subclasses. Choose @staticmethod when the method is a pure utility that does not depend on class or instance context. The python classmethod decorator is the right tool for factory methods and any logic that must know which class it is called on.

python classmethod decorator: Practical Usage and Code Examp | RYUSLOG DEV